diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/Module.manifest b/Ghidra/Debug/Debugger-agent-x64dbg/Module.manifest new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/Module.manifest @@ -0,0 +1 @@ + diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/README.md b/Ghidra/Debug/Debugger-agent-x64dbg/README.md new file mode 100644 index 0000000000..5497d72c08 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/README.md @@ -0,0 +1 @@ +# Debugger-agent-x64dbg diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/build.gradle b/Ghidra/Debug/Debugger-agent-x64dbg/build.gradle new file mode 100644 index 0000000000..8385fbd691 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/build.gradle @@ -0,0 +1,33 @@ +/* ### + * 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. + */ +// Not technically a Java project, but required to be a Help project +apply from: "${rootProject.projectDir}/gradle/javaProject.gradle" +apply from: "${rootProject.projectDir}/gradle/helpProject.gradle" +apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" +apply from: "$rootProject.projectDir/gradle/nativeProject.gradle" +apply from: "$rootProject.projectDir/gradle/hasPythonPackage.gradle" + +apply plugin: 'eclipse' +eclipse.project.name = 'Debug Debugger-agent-x64dbg' + +dependencies { + // Only for Help :/ + api project(':Debugger-rmi-trace') +} + +tasks.assemblePyPackage { +} + diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest b/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest new file mode 100644 index 0000000000..49f3984ab1 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest @@ -0,0 +1,13 @@ +##VERSION: 2.0 +##MODULE IP: Apache License 2.0 +##MODULE IP: MIT +Module.manifest||GHIDRA||||END| +README.md||GHIDRA||||END| +src/main/help/help/TOC_Source.xml||GHIDRA||||END| +src/main/help/help/topics/x64dbg/x64dbg.html||GHIDRA||||END| +src/main/py/LICENSE||GHIDRA||||END| +src/main/py/MANIFEST.in||GHIDRA||||END| +src/main/py/README.md||GHIDRA||||END| +src/main/py/pyproject.toml||GHIDRA||||END| +src/main/py/src/ghidraxdbg/py.typed||GHIDRA||||END| +src/main/py/src/ghidraxdbg/schema.xml||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg-attach.bat b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg-attach.bat new file mode 100644 index 0000000000..25c2531572 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg-attach.bat @@ -0,0 +1,34 @@ +:: ### +:: 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 x64dbg attach +::@desc +::@desc

Attach with x64dbg (in a Python interpreter)

+::@desc

+::@desc This will attach to a running target on the local machine using x64dbg.dll. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group x64dbg +::@icon icon.debugger +::@help x64dbg#attach +::@depends Debugger-rmi-trace +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_TARGET_PID:int=0 "Process id" "The target process id" +::@env OPT_X64DBG_EXE:file="C:\\Software\\release\\x64\\x64dbg.exe" "Path to x64dbg.exe" "Path to x64dbg.exe (or equivalent)." + +@echo off + +"%OPT_PYTHON_EXE%" -i ..\support\local-x64dbg-attach.py diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat new file mode 100644 index 0000000000..73d5c1e8fd --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/debugger-launchers/local-x64dbg.bat @@ -0,0 +1,38 @@ +:: ### +:: 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 x64dbg +::@image-opt env:OPT_TARGET_IMG +::@desc +::@desc

Launch with x64dbg (in a Python interpreter)

+::@desc

+::@desc This will launch the target on the local machine using x64dbg.dll. +::@desc For setup instructions, press F1. +::@desc

+::@desc +::@menu-group x64dbg +::@icon icon.debugger +::@help x64dbg#local +::@depends Debugger-rmi-trace +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +:: Use env instead of args, because "all args except first" is terrible to implement in batch +::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image" +::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" +::@env OPT_TARGET_DIR:str="" "Dir" "Initial directory" +::@env OPT_X64DBG_EXE:file="C:\\Software\\release\\x64\\x64dbg.exe" "Path to x64dbg.exe" "Path to x64dbg.exe (or equivalent)." + +@echo off + +"%OPT_PYTHON_EXE%" -i ..\support\local-x64dbg.py diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py new file mode 100644 index 0000000000..5885d3e8b6 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg-attach.py @@ -0,0 +1,62 @@ +## ### +# 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. +## + +import os +import sys + + +def append_paths(): + sys.path.append( + f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support") + from gmodutils import ghidra_module_pypath + sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) + sys.path.append(ghidra_module_pypath()) + + +def main(): + append_paths() + # Delay these imports until sys.path is patched + from ghidraxdbg import commands as cmd + from ghidraxdbg.hooks import on_state_changed + from ghidraxdbg.util import dbg + + # So that the user can re-enter by typing repl() + global repl + repl = cmd.repl + + cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR')) + cmd.ghidra_trace_attach(os.getenv('OPT_TARGET_PID'), start_trace=False) + + try: + dbg.wait() + except KeyboardInterrupt as ki: + dbg.interrupt() + + cmd.ghidra_trace_start(os.getenv('OPT_TARGET_PID')) + cmd.ghidra_trace_sync_enable() + + cmd.ghidra_trace_txstart() + cmd.ghidra_trace_put_all() + + cmd.repl() + + +if __name__ == '__main__': + try: + main() + except SystemExit as x: + if x.code != 0: + print(f"Exited with code {x.code}") diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py new file mode 100644 index 0000000000..c93ecfc8c5 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/data/support/local-x64dbg.py @@ -0,0 +1,69 @@ +## ### +# 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. +## + +import os +import sys + + +def append_paths(): + sys.path.append( + f"{os.getenv('MODULE_Debugger_rmi_trace_HOME')}/data/support") + from gmodutils import ghidra_module_pypath + sys.path.append(ghidra_module_pypath("Debugger-rmi-trace")) + sys.path.append(ghidra_module_pypath()) + + +def main(): + append_paths() + # Delay these imports until sys.path is patched + from ghidraxdbg import commands as cmd + from ghidraxdbg.hooks import on_state_changed + from ghidraxdbg.util import dbg + + # So that the user can re-enter by typing repl() + global repl + repl = cmd.repl + + cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR')) + args = os.getenv('OPT_TARGET_ARGS') + initdir = os.getenv('OPT_TARGET_DIR') + target = os.getenv('OPT_TARGET_IMG') + + cmd.ghidra_trace_create(target, args=args, initdir=initdir, start_trace=False) + + try: + dbg.wait() + except KeyboardInterrupt as ki: + dbg.interrupt() + + cmd.ghidra_trace_start(target) + cmd.ghidra_trace_sync_enable() + + cmd.ghidra_trace_txstart() + if target is None or target == "": + cmd.ghidra_trace_put_available() + else: + cmd.ghidra_trace_put_all() + + cmd.repl() + + +if __name__ == '__main__': + try: + main() + except SystemExit as x: + if x.code != 0: + print(f"Exited with code {x.code}") diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml new file mode 100644 index 0000000000..72360c1bea --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/TOC_Source.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html new file mode 100644 index 0000000000..bcaa0eceff --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/help/help/topics/x64dbg/x64dbg.html @@ -0,0 +1,102 @@ + + + + + + + Debugger Launchers: x64dbg Debugger + + + + + +

Debugger Launchers: x64dbg Debugger

+ +

Integration with x64dbg is achieved using the Python 3 + API x64dbg-automate-pyclient and underlying plugin x64dbg-automate, kindly provided by Darius Houle + (see https://github.com/dariushoule/x64dbg-automate & x64dbg-automate-pyclient). The console + debugger launches a full x64dbg session by default, synchronized with the + Ghidra debugger UI.

+ +

Two launchers are included out of the box, one for a local process and one for a local pid:

+ +

Local

+ +

The plain "local-x64dbg" launches the current program as a user-mode process + on the local system. If there is no current program, the user may specify the Image option + explicitly or launch x64dbg without a target.

+ +

Setup

+ +

Make sure you have installed the executables for x64dbg-automate (typically the contents + of x64dbg/build[32|64]/Release) in the plugins directory for x64dbg (release/x[32|64]/plugins).

+ +

If you have access to PyPI, setting up your Python 3 environment is done using Pip. (Please + note the version specifier for Protobuf.)

+ + + +

If you are offline, or would like to use our provided packages, we still use Pip, but with a + more complicated invocation:

+ + + +

Options

+ + + +

Once running, you are presented with a command-line interface in Ghidra's Terminal. This CLI + accepts your usual x64dbg native commands. You can escape from this CLI and enter a Python 3 REPL + by entering ".exit". This is not an actual x64dbg command, but our implementation + understands this to mean exit the x64dbg REPL. From the Python 3 REPL, you can access the + underlying Python-based API x64dbg_automate. This is an uncommon need, but may be useful for + diagnostics and/or workarounds. To re-enter the x64dbg REPL, enter "repl()". + Alternatively, if you are trying to quit, but typed ".exit", just type + "quit()" to terminate the session.

+ + +

Attach

+ +

This launcher allows the user to attach to a local running process. Options are the same as + those for the base x64dbg, except Process Id replaces Image.

+ +

Options

+ +