From f9bea7720a033bec7cb438c5fe25158005e8728d Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Tue, 26 Mar 2024 08:50:53 -0400 Subject: [PATCH] GP-4439: Add raw-gdb.sh and raw-python.sh. Add @no-image tag. --- .../data/debugger-launchers/raw-gdb.sh | 57 +++ .../src/main/py/src/ghidragdb/hooks.py | 2 +- .../api/tracermi/TraceRmiLaunchOffer.java | 14 +- .../data/debugger-launchers/raw-python3.sh | 43 +++ .../data/support/raw-python3.py | 36 ++ .../AbstractScriptTraceRmiLaunchOffer.java | 9 +- .../launcher/AbstractTraceRmiLaunchOffer.java | 340 ++++++++---------- .../gui/tracermi/launcher/LaunchAction.java | 118 ++---- .../launcher/LaunchFailureDialog.java | 132 +++++++ .../launcher/ScriptAttributesParser.java | 58 +-- .../TraceRmiLauncherServicePlugin.java | 147 +++++++- .../service/tracermi/TraceRmiHandler.java | 4 +- .../src/main/py/src/ghidratrace/client.py | 15 +- .../plugin/core/terminal/TerminalPanel.java | 4 +- .../core/terminal/TerminalProvider.java | 3 + .../main/java/ghidra/pty/unix/UnixPty.java | 2 + .../java/ghidra/pty/unix/UnixPtyEndpoint.java | 8 +- 17 files changed, 655 insertions(+), 337 deletions(-) create mode 100755 Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh create mode 100755 Ghidra/Debug/Debugger-rmi-trace/data/debugger-launchers/raw-python3.sh create mode 100644 Ghidra/Debug/Debugger-rmi-trace/data/support/raw-python3.py create mode 100644 Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/LaunchFailureDialog.java diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh new file mode 100755 index 0000000000..3a2b8224ec --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +#@title raw gdb +#@no-image +#@desc
+#@descThis will start gdb and connect to it. It will not launch +#@desc a target, so you can (must) set up your target manually. +#@desc GDB must already +#@desc be installed on your system, and it must embed the Python 3 interpreter. You will also +#@desc need protobuf and psutil installed for Python 3.
+#@desc +#@menu-group raw +#@icon icon.debugger +#@help TraceRmiLauncherServicePlugin#gdb +#@env OPT_GDB_PATH:str="gdb" "Path to gdb" "The path to gdb. Omit the full path to resolve using the system PATH." +#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" + +if [ -d ${GHIDRA_HOME}/ghidra/.git ] +then + export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH + export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +elif [ -d ${GHIDRA_HOME}/.git ] +then + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +else + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH +fi + +"$OPT_GDB_PATH" \ + -q \ + -ex "set pagination off" \ + -ex "set confirm off" \ + -ex "show version" \ + -ex "python import ghidragdb" \ + -ex "set architecture $OPT_ARCH" \ + -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ + -ex "ghidra trace start" \ + -ex "ghidra trace sync-enable" \ + -ex "set confirm on" \ + -ex "set pagination on" diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py index 8756f98195..060318dcd3 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py @@ -48,8 +48,8 @@ class HookState(object): def end_batch(self): if self.batch is None: return - commands.STATE.client.end_batch() self.batch = None + commands.STATE.client.end_batch() def check_skip_continue(self): skip = self.skip_continue diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java index 1f30063ab8..bd69e0310c 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java @@ -52,6 +52,7 @@ public interface TraceRmiLaunchOffer { * @param sessions any terminal sessions created while launching the back-end. If there are more * than one, they are distinguished by launcher-defined keys. If there are no * sessions, then there was likely a catastrophic error in the launcher. + * @param acceptor the acceptor if waiting for a connection * @param connection if the target connected back to Ghidra, that connection * @param trace if the connection started a trace, the (first) trace it created * @param exception optional error, if failed @@ -138,7 +139,7 @@ public interface TraceRmiLaunchOffer { /** * Re-write the launcher arguments, if desired * - * @param launcher the launcher that will create the target + * @param offer the offer that will create the target * @param arguments the arguments suggested by the offer or saved settings * @param relPrompt describes the timing of this callback relative to prompting the user * @return the adjusted arguments @@ -176,7 +177,7 @@ public interface TraceRmiLaunchOffer { * memorized. The opinion will generate each offer fresh each time, so it's important that the * "same offer" have the same configuration name. Note that the name cannot depend on * the program name, but can depend on the model factory and program language and/or compiler - * spec. This name cannot contain semicolons ({@ code ;}). + * spec. This name cannot contain semicolons ({@code ;}). * * @return the configuration name */ @@ -262,6 +263,8 @@ public interface TraceRmiLaunchOffer { * The order of entries in the quick-launch drop-down menu is always most-recently to * least-recently used. An entry that has never been used does not appear in the quick launch * menu. + * + * @return the sub-group name for ordering in the menu */ default String getMenuOrder() { return ""; @@ -285,4 +288,11 @@ public interface TraceRmiLaunchOffer { * @return the parameters */ MapThis will start python, import ghidratrace and connect to it. +#@desc This connector is made for those wanting to explore the TraceRMI API and possibly develop +#@desc a new connector. You will need protobuf installed for Python 3.
+#@desc +#@menu-group raw +#@icon icon.debugger +#@help TraceRmiLauncherServicePlugin#gdb +#@env OPT_PYTHON_EXE:str="python" "Path to python" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +#@env OPT_LANG:str="DATA:LE:64:default" "Ghidra Language" "The Ghidra LanguageID for the trace" +#@env OPT_COMP:str="pointer64" "Ghidra Compiler" "The Ghidra CompilerSpecID for the trace" + +if [ -d ${GHIDRA_HOME}/ghidra/.git ] +then + export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +elif [ -d ${GHIDRA_HOME}/.git ] +then + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +else + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH +fi + +"$OPT_PYTHON_EXE" -i ../support/raw-python3.py diff --git a/Ghidra/Debug/Debugger-rmi-trace/data/support/raw-python3.py b/Ghidra/Debug/Debugger-rmi-trace/data/support/raw-python3.py new file mode 100644 index 0000000000..db0f8f2bdc --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/data/support/raw-python3.py @@ -0,0 +1,36 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from concurrent.futures import ThreadPoolExecutor +import os +import socket +import sys + +from ghidratrace import * +from ghidratrace.client import * + + +REGISTRY = MethodRegistry(ThreadPoolExecutor(max_workers=1)) + +host = os.getenv("GHIDRA_TRACE_RMI_HOST") +port = int(os.getenv("GHIDRA_TRACE_RMI_PORT")) +c = socket.socket() +c.connect((host, port)) +client = Client( + c, f"python-{sys.version_info.major}.{sys.version_info.minor}", REGISTRY) +print(f"Connected to {client.description} at {host}:{port}") + +trace = client.create_trace("noname", os.getenv( + "OPT_LANG"), os.getenv("OPT_COMP")) diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java index ee2e90b327..effa0aac33 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java @@ -102,7 +102,9 @@ public abstract class AbstractScriptTraceRmiLaunchOffer extends AbstractTraceRmi List- Check the Terminal! - If no terminal is visible, check the menus: Window → Terminals → - .... - A path or other configuration parameter may be incorrect. - The back-end debugger may have paused for user input. - There may be a missing dependency. - There may be an incorrect version, etc.
- -+ Check the Terminal! + If no terminal is visible, check the menus: Window → Terminals → + .... + A path or other configuration parameter may be incorrect. + The back-end debugger may have paused for user input. + There may be a missing dependency. + There may be an incorrect version, etc.
+ + """; + private static final String MSGPAT_PART_RESOURCES = """ +* The terminal will no longer respond to the window resizing, and scrollbars are displayed as * needed. If the terminal size changes as a result of this call, - * {@link TerminalListener#resized(int, int)} is invoked. + * {@link TerminalListener#resized(short, short)} is invoked. * * @param cols the number of columns * @param rows the number of rows @@ -699,7 +699,7 @@ public class TerminalPanel extends JPanel implements FieldLocationListener, Fiel *
* Immediately fit the terminal to the window. It will also respond to the window resizing by * recalculating the rows and columns and adjusting the buffer's contents to fit. Whenever the - * terminal size changes {@link TerminalListener#resized(int, int)} is invoked. The bottom + * terminal size changes {@link TerminalListener#resized(short, short)} is invoked. The bottom * scrollbar is disabled, and the vertical scrollbar is always displayed, to avoid frenetic * horizontal resizing. */ diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java index e76a82a865..25f7fa0d04 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java @@ -365,6 +365,9 @@ public class TerminalProvider extends ComponentProviderAdapter { terminated = true; removeLocalAction(actionTerminate); panel.terminalListeners.clear(); + panel.setOutputCallback(buf -> { + }); + panel.getFieldPanel().setCursorOn(false); setTitle("[Terminal]"); setSubTitle("Terminated"); if (!isVisible()) { diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPty.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPty.java index 37f7019cac..66cc987f71 100644 --- a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPty.java +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPty.java @@ -68,6 +68,8 @@ public class UnixPty implements Pty { if (closed) { return; } + child.closeStreams(); + parent.closeStreams(); LIB_POSIX.close(achild); LIB_POSIX.close(aparent); closed = true; diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPtyEndpoint.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPtyEndpoint.java index dc2ba76cde..90ff133d70 100644 --- a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPtyEndpoint.java +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/unix/UnixPtyEndpoint.java @@ -15,8 +15,7 @@ */ package ghidra.pty.unix; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import ghidra.pty.PtyEndpoint; import ghidra.pty.unix.PosixC.Ioctls; @@ -43,4 +42,9 @@ public class UnixPtyEndpoint implements PtyEndpoint { public InputStream getInputStream() { return inputStream; } + + protected void closeStreams() throws IOException { + outputStream.close(); + inputStream.close(); + } }