Created
September 3, 2024 18:41
-
-
Save redthing1/ad3f4efc5aad10d70b14a97e3e1d739c to your computer and use it in GitHub Desktop.
binsync's ghidra plugin, fixed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A cross-decompiler collaboration plugin | |
# @author BinSync Team | |
# @category Collaboration | |
# @menupath Tools.BinSync.Start UI... | |
import os | |
plugin_command = "binsync -s ghidra" | |
def create_plugin(*args, **kwargs): | |
# REPLACE_ME this import with an import of your plugin's create_plugin function | |
from binsync import create_plugin as _create_plugin | |
return _create_plugin(*args, **kwargs) | |
# ============================================================================= | |
# LibBS generic plugin loader (don't touch things below this) | |
# ============================================================================= | |
import sys | |
# Python 2 has special requirements for Ghidra, which forces us to use a different entry point | |
# and scope for defining plugin entry points. | |
# The Python 3 side has been edited since currently every supported decompiler must import create_plugin | |
if sys.version[0] == "2": | |
# Do Ghidra Py2 entry point | |
import subprocess | |
from libbs_vendored.ghidra_bridge_server import GhidraBridgeServer | |
# get current user's PATH environment variable from their shell | |
# and set it as the PATH for the subprocess | |
# this is necessary because Ghidra does not inherit the user's PATH | |
# run bash and source the user's shell profile to get the PATH | |
user_path_proc = subprocess.Popen( | |
"bash -c 'source ~/.bash_profile; echo $PATH'", | |
stdout=subprocess.PIPE, | |
shell=True, | |
) | |
user_path = user_path_proc.communicate()[0].decode("utf-8").strip() | |
print("User PATH: {}".format(user_path)) | |
plugin_cmd_parts = plugin_command.split(" ") | |
plugin_cmd_base = plugin_cmd_parts[0] | |
plugin_cmd_args = plugin_cmd_parts[1:] | |
# find the full path to the plugin command in the user's PATH | |
plugin_cmd_path = None | |
for path in user_path.split(":"): | |
plugin_cmd_path = os.path.join(path, plugin_cmd_base) | |
if os.path.exists(plugin_cmd_path): | |
break | |
GhidraBridgeServer.run_server(background=True) | |
# print(f"Starting Ghidra Bridge Server: plugin_command={plugin_command}") # python2 does not support f-strings | |
print("Starting Ghidra Bridge Server: plugin_command={}".format(plugin_command)) | |
try: | |
# process = subprocess.Popen(plugin_command.split(" ")) | |
cmd_parts = [plugin_cmd_path] + plugin_cmd_args | |
process = subprocess.Popen(cmd_parts) | |
print("Plugin started with PID: {}".format(process.pid)) | |
except Exception as e: | |
raise RuntimeError( | |
"Failed to run the Python3 backed. It's likely Python3 is not in your Path inside Ghidra. Error: {}".format( | |
e | |
) | |
) | |
if process.poll() is not None: | |
raise RuntimeError( | |
"Failed to run the Python3 backed. It's likely Python3 is not in your Path inside Ghidra." | |
) | |
def PLUGIN_ENTRY(*args, **kwargs): | |
""" | |
This is the entry point for IDA to load the plugin. | |
""" | |
return create_plugin(*args, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment