Skip to content
This repository has been archived by the owner on Jun 24, 2023. It is now read-only.

Commit

Permalink
All the old features are now working again
Browse files Browse the repository at this point in the history
  • Loading branch information
hugsy committed May 13, 2020
1 parent db653ce commit 63e4a26
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 111 deletions.
125 changes: 74 additions & 51 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@
info,
err,
dbg,
add_gef_breakpoint,
delete_gef_breakpoint,
RunInBackground,
)

from .constants import (
Expand All @@ -64,28 +63,50 @@
)


__service_started = False
__service_thread = None
__gef_instance = None


def is_service_started():
global __service_thread
return __service_thread is not None


def gef_add_breakpoint(bv, addr):
global __gef_instance
if __gef_instance is None:
return False
return __gef_instance.add_breakpoint(bv, addr)


def create_binja_menu():
def gef_del_breakpoint(bv, addr):
global __gef_instance
if __gef_instance is None:
return False
return __gef_instance.delete_breakpoint(bv, addr)


def register_gef_breakpoint_menu():
# Binja does not really support menu in its GUI just yet
PluginCommand.register_for_address(
"gef : add breakpoint",
"GEF\\Set breakpoint",
"Add a breakpoint in gef at the specified location.",
add_gef_breakpoint
gef_add_breakpoint,
is_valid = lambda view, addr: is_service_started()
)

PluginCommand.register_for_address(
"gef : delete breakpoint",
"GEF\\Delete breakpoint",
"Remove a breakpoint in gef at the specified location.",
delete_gef_breakpoint
gef_del_breakpoint,
is_valid = lambda view, addr: is_service_started()
)
return


def start_service(host, port, bv):
""" Starting the service """
global __gef_instance
info("Starting service on {}:{}".format(host, port))
server = xmlrpc.server.SimpleXMLRPCServer(
(host, port),
Expand All @@ -94,71 +115,73 @@ def start_service(host, port, bv):
allow_none=True
)
server.register_introspection_functions()
server.register_instance(Gef(server, bv))
__gef_instance = Gef(server, bv)
server.register_instance(__gef_instance)
dbg("Registered {} functions.".format( len(server.system_listMethods()) ))
while True:
if hasattr(server, "shutdown") and server.shutdown==True: break
server.handle_request()
return


def gef_start(bv):
global __service_thread, __service_started
__service_thread = threading.Thread(target=start_service, args=(HOST, PORT, bv))
__service_thread.daemon = True
__service_thread.start()
dbg("Started new thread '{}'".format(__service_thread.name))

if not __service_started:
create_binja_menu()
__service_started = True
return
def shutdown_service():
try:
cli = xmlrpc.client.ServerProxy("http://{:s}:{:d}".format(HOST, PORT))
cli.shutdown()
except socket.error:
pass


def gef_stop(bv):
def stop_service():
""" Stopping the service """
global __service_thread
dbg("Trying to stop service thread")
shutdown_service()
__service_thread.join()
__service_thread = None
info("Server stopped")
return


def gef_start_stop(bv):
if __service_thread is None:
dbg("Trying to start service thread")
gef_start(bv)
show_message_box(
"GEF",
"Service successfully started, you can now have gef connect to it",
MessageBoxButtonSet.OKButtonSet,
MessageBoxIcon.InformationIcon
)

else:
dbg("Trying to stop service thread")
try:
cli = xmlrpc.client.ServerProxy("http://{:s}:{:d}".format(HOST, PORT))
cli.shutdown()
except socket.error:
pass

gef_stop(bv)
show_message_box(
"GEF",
"Service successfully stopped",
MessageBoxButtonSet.OKButtonSet,
MessageBoxIcon.InformationIcon
)
def gef_start(bv):
global __service_thread
dbg("Starting background service...")
__service_thread = threading.Thread(target=start_service, args=(HOST, PORT, bv))
__service_thread.daemon = True
__service_thread.start()
register_gef_breakpoint_menu()
show_message_box(
"GEF",
"Service successfully started, you can now have gef connect to it",
MessageBoxButtonSet.OKButtonSet,
MessageBoxIcon.InformationIcon
)
return


def gef_stop(bv):
"Stopping background service... "
stop_service()
show_message_box(
"GEF",
"Service successfully stopped",
MessageBoxButtonSet.OKButtonSet,
MessageBoxIcon.InformationIcon
)
return



PluginCommand.register(
"GEF\\Start service",
"Start the service for communicating with gef",
gef_start,
is_valid = lambda view: not is_service_started()
)


PluginCommand.register(
"Start/stop server GEF interaction",
"Start/stop the XMLRPC server for communicating with gef",
gef_start_stop
"GEF\\Stop service",
"Stop the service for communicating with gef",
gef_stop,
is_valid = lambda view: is_service_started()
)
94 changes: 64 additions & 30 deletions gef.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
core_version,
log_info,
highlight,

)

from .constants import (
PAGE_SIZE,
DEBUG,
HL_NO_COLOR,
HL_BP_COLOR,
HL_CUR_INSN_COLOR,
)

Expand All @@ -23,11 +23,6 @@
expose,
is_exposed,
ishex,
g_breakpoints,
g_current_instruction,
hl,
add_gef_breakpoint,
delete_gef_breakpoint,
)

from xmlrpc.server import (
Expand All @@ -50,7 +45,11 @@ def __init__(self, server, bv, *args, **kwargs):
self.view = bv
self.base = bv.entry_point & ~(PAGE_SIZE-1)
self._version = ("Binary Ninja", core_version())
self.old_bps = set()
self.__old_bps = set()
self.__breakpoints = set()
tag_type = bv.tag_types["Breakpoints"]
self.__bp_tag = bv.create_tag(tag_type, "GEF Breakpoint", True)
self.__current_instruction = 0
return


Expand Down Expand Up @@ -108,16 +107,21 @@ def version(self):
def jump(self, address):
""" Jump(int addr) => None
Move the EA pointer to the address pointed by `addr`.
Example: binaryninja Jump 0x4049de
Example: binaryninja jump 0x4049de
"""
addr = int(address, 0)
return self.view.file.navigate(self.view.file.view, addr)
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!"
Example: binaryninja makecomm 0x40000 "Important call here!"
"""
addr = int(address, 0)
start_addr = self.view.get_previous_function_start_before(addr)
Expand All @@ -128,57 +132,87 @@ def makecomm(self, address, comment):
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
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 hl(self.view, addr, color)
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.
Synchronize debug info with gef. This is an internal function. It is not recommended using it from the command line.
Example: binaryninja sync
"""
global g_current_instruction

off = int(off, 0)
pc = self.base + off
if DEBUG: log_info("[*] current_pc=%#x , old_pc=%#x" % (pc, g_current_instruction))
if DEBUG: log_info("[*] current_pc=%#x , old_pc=%#x" % (pc, self.__current_instruction))

# unhighlight the _current_instruction
if g_current_instruction > 0:
hl(self.view, g_current_instruction, HL_NO_COLOR)
hl(self.view, pc, HL_CUR_INSN_COLOR)
if self.__current_instruction > 0:
self.highlight(self.__current_instruction, HL_NO_COLOR)
self.highlight(pc, HL_CUR_INSN_COLOR)

# update the _current_instruction
g_current_instruction = pc

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" % (g_breakpoints))
dbg("pre-binja-breakpoints: %s" % (self.__breakpoints))

bn_added = [ x-self.base for x in g_breakpoints if x not in self.old_bps ]
bn_removed = [ x-self.base for x in self.old_bps if x not in g_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:
add_gef_breakpoint(self.view, self.base + bp)
self.add_breakpoint(self.view, self.base + bp)

for bp in removed:
delete_gef_breakpoint(self.view, self.base + bp)
self.delete_breakpoint(self.view, self.base + bp)

self.old_bps = copy.deepcopy(g_breakpoints)
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" % (g_breakpoints,))
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",)
Loading

0 comments on commit 63e4a26

Please sign in to comment.