Skip to content

Commit 57400d8

Browse files
committed
Merge branch 'GP-5138_ryanmkurtz_ghidradev'
2 parents 37ed090 + 31ee251 commit 57400d8

35 files changed

+1297
-312
lines changed

Ghidra/Features/Base/certification.manifest

+1
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,7 @@ src/main/resources/images/pencil16.png||GHIDRA||||END|
898898
src/main/resources/images/pin.png||GHIDRA||||END|
899899
src/main/resources/images/play_again.png||GHIDRA||||END|
900900
src/main/resources/images/preferences-system.png||Tango Icons - Public Domain|||tango|END|
901+
src/main/resources/images/python.png||GHIDRA||||END|
901902
src/main/resources/images/question_zero.png||GHIDRA||||END|
902903
src/main/resources/images/red-cross.png||GHIDRA||||END|
903904
src/main/resources/images/redQuestionMark.png||GHIDRA||||END|
Loading
Binary file not shown.

Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/launcher.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,14 @@ def __init__(self, verbose=False, *, install_dir: Path = None):
160160
install_dir = install_dir or os.getenv("GHIDRA_INSTALL_DIR")
161161
self._install_dir = self._validate_install_dir(install_dir)
162162

163+
java_home_override = os.getenv("JAVA_HOME_OVERRIDE")
164+
if java_home_override:
165+
self._java_home = java_home_override
166+
163167
# check if we are in the ghidra source tree
164168
support = Path(install_dir) / "support"
165169
if not support.exists():
166170
self._dev_mode = True
167-
self._java_home = os.getenv("JAVA_HOME_OVERRIDE")
168171

169172
self._plugins: List[Tuple[Path, ExtensionDetails]] = []
170173
self.verbose = verbose
@@ -469,7 +472,7 @@ def start(self, **jpype_kwargs):
469472
self._pre_launch_init()
470473
self._launch()
471474
except Exception as e:
472-
self._report_fatal_error("An error occured launching Ghidra", str(e), e)
475+
self._report_fatal_error("An error occurred launching Ghidra", str(e), e)
473476

474477
def get_install_path(self, plugin_name: str) -> Path:
475478
"""

GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<feature
33
id="ghidra.ghidradev"
44
label="GhidraDev"
5-
version="4.0.1.qualifier"
5+
version="5.0.0.qualifier"
66
provider-name="Ghidra">
77

88
<description>

GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/.launch/GhidraDev.launch

+22-13
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@
167167
<setEntry value="com.google.guava.failureaccess@default:default"/>
168168
<setEntry value="com.google.guava@default:default"/>
169169
<setEntry value="com.ibm.icu@default:default"/>
170-
<setEntry value="com.python.pydev.analysis*6.3.1.201802272029@default:default"/>
170+
<setEntry value="com.python.pydev.analysis*9.3.0.202203051235@default:default"/>
171+
<setEntry value="com.python.pydev.debug*9.3.0.202203051235@default:default"/>
172+
<setEntry value="com.python.pydev.refactoring*9.3.0.202203051235@default:default"/>
171173
<setEntry value="com.sun.el.javax.el@default:default"/>
172174
<setEntry value="com.sun.jna.platform@default:default"/>
173175
<setEntry value="com.sun.jna@default:default"/>
@@ -176,7 +178,6 @@
176178
<setEntry value="jakarta.inject.jakarta.inject-api*1.0.5@default:default"/>
177179
<setEntry value="jakarta.inject.jakarta.inject-api*2.0.1@default:default"/>
178180
<setEntry value="jakarta.servlet-api@default:default"/>
179-
<setEntry value="javax.xml@default:default"/>
180181
<setEntry value="jaxen@default:default"/>
181182
<setEntry value="org.apache.aries.spifly.dynamic.bundle@default:default"/>
182183
<setEntry value="org.apache.batik.constants@default:default"/>
@@ -202,6 +203,8 @@
202203
<setEntry value="org.apache.xml.resolver@default:default"/>
203204
<setEntry value="org.apache.xml.serializer@default:default"/>
204205
<setEntry value="org.apache.xmlgraphics@default:default"/>
206+
<setEntry value="org.commonmark-gfm-tables@default:default"/>
207+
<setEntry value="org.commonmark@default:default"/>
205208
<setEntry value="org.eclipse.ant.core@default:default"/>
206209
<setEntry value="org.eclipse.buildship.compat@default:default"/>
207210
<setEntry value="org.eclipse.buildship.core@default:default"/>
@@ -296,7 +299,7 @@
296299
<setEntry value="org.eclipse.help.base@default:default"/>
297300
<setEntry value="org.eclipse.help.ui@default:default"/>
298301
<setEntry value="org.eclipse.help@default:default"/>
299-
<setEntry value="org.eclipse.jdt.annotation*2.3.0.v20240111-2306@default:default"/>
302+
<setEntry value="org.eclipse.jdt.annotation@default:default"/>
300303
<setEntry value="org.eclipse.jdt.core.compiler.batch@default:default"/>
301304
<setEntry value="org.eclipse.jdt.core.manipulation@default:default"/>
302305
<setEntry value="org.eclipse.jdt.core@default:default"/>
@@ -308,10 +311,11 @@
308311
<setEntry value="org.eclipse.jdt.launching@default:default"/>
309312
<setEntry value="org.eclipse.jdt.ui@default:default"/>
310313
<setEntry value="org.eclipse.jem.util@default:default"/>
314+
<setEntry value="org.eclipse.jetty.ee10.servlet@default:default"/>
315+
<setEntry value="org.eclipse.jetty.ee10.webapp@default:default"/>
311316
<setEntry value="org.eclipse.jetty.ee8.security@default:default"/>
312317
<setEntry value="org.eclipse.jetty.ee8.server@default:default"/>
313318
<setEntry value="org.eclipse.jetty.ee8.servlet@default:default"/>
314-
<setEntry value="org.eclipse.jetty.ee8.webapp@default:default"/>
315319
<setEntry value="org.eclipse.jetty.ee@default:default"/>
316320
<setEntry value="org.eclipse.jetty.http@default:default"/>
317321
<setEntry value="org.eclipse.jetty.io@default:default"/>
@@ -414,14 +418,19 @@
414418
<setEntry value="org.osgi.util.position@default:default"/>
415419
<setEntry value="org.osgi.util.promise@default:default"/>
416420
<setEntry value="org.osgi.util.xml@default:default"/>
417-
<setEntry value="org.python.pydev*6.3.1.201802272029@default:default"/>
418-
<setEntry value="org.python.pydev.ast*6.3.1.201802272029@default:default"/>
419-
<setEntry value="org.python.pydev.core*6.3.1.201802272029@default:default"/>
420-
<setEntry value="org.python.pydev.jython*6.3.1.201802272029@default:default"/>
421-
<setEntry value="org.python.pydev.parser*6.3.1.201802272029@default:default"/>
422-
<setEntry value="org.python.pydev.shared_core*6.3.1.201802272029@default:default"/>
423-
<setEntry value="org.python.pydev.shared_interactive_console*6.3.1.201802272029@default:default"/>
424-
<setEntry value="org.python.pydev.shared_ui*6.3.1.201802272029@default:default"/>
421+
<setEntry value="org.python.pydev*9.3.0.202203051235@default:default"/>
422+
<setEntry value="org.python.pydev.ast*9.3.0.202203051235@default:default"/>
423+
<setEntry value="org.python.pydev.core*9.3.0.202203051235@default:default"/>
424+
<setEntry value="org.python.pydev.customizations*9.3.0.202203051235@default:default"/>
425+
<setEntry value="org.python.pydev.debug*9.3.0.202203051235@default:default"/>
426+
<setEntry value="org.python.pydev.django*9.3.0.202203051235@default:default"/>
427+
<setEntry value="org.python.pydev.help*9.3.0.202203051235@default:default"/>
428+
<setEntry value="org.python.pydev.jython*9.3.0.202203051235@default:default"/>
429+
<setEntry value="org.python.pydev.parser*9.3.0.202203051235@default:default"/>
430+
<setEntry value="org.python.pydev.refactoring*9.3.0.202203051235@default:default"/>
431+
<setEntry value="org.python.pydev.shared_core*9.3.0.202203051235@default:default"/>
432+
<setEntry value="org.python.pydev.shared_interactive_console*9.3.0.202203051235@default:default"/>
433+
<setEntry value="org.python.pydev.shared_ui*9.3.0.202203051235@default:default"/>
425434
<setEntry value="org.sat4j.core@default:default"/>
426435
<setEntry value="org.sat4j.pb@default:default"/>
427436
<setEntry value="org.tukaani.xz@default:default"/>
@@ -430,7 +439,7 @@
430439
<setAttribute key="selected_workspace_bundles">
431440
<setEntry value="ghidra.ghidradev@default:default"/>
432441
</setAttribute>
433-
<booleanAttribute key="show_selected_only" value="true"/>
442+
<booleanAttribute key="show_selected_only" value="false"/>
434443
<booleanAttribute key="tracing" value="false"/>
435444
<booleanAttribute key="useCustomFeatures" value="false"/>
436445
<booleanAttribute key="useDefaultConfig" value="true"/>

GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Manifest-Version: 1.0
33
Bundle-ManifestVersion: 2
44
Bundle-Name: GhidraDev
55
Bundle-SymbolicName: ghidra.ghidradev;singleton:=true
6-
Bundle-Version: 4.0.1.qualifier
6+
Bundle-Version: 5.0.0.qualifier
77
Bundle-Activator: ghidradev.Activator
88
Require-Bundle: org.eclipse.ant.core;bundle-version="3.7.200",
99
org.eclipse.buildship.core;bundle-version="3.1.8",
@@ -21,10 +21,11 @@ Require-Bundle: org.eclipse.ant.core;bundle-version="3.7.200",
2121
org.eclipse.ltk.core.refactoring;bundle-version="3.14.200",
2222
org.eclipse.ui;bundle-version="3.205.0",
2323
org.eclipse.ui.ide;bundle-version="3.22.0",
24-
com.python.pydev.debug;bundle-version="6.3.1";resolution:=optional,
25-
org.python.pydev;bundle-version="[6.3.1,10.0.0)";resolution:=optional,
26-
org.python.pydev.core;bundle-version="[6.3.1,10.0.0)";resolution:=optional,
27-
org.python.pydev.ast;bundle-version="[6.3.1,10.0.0)";resolution:=optional,
24+
com.python.pydev.debug;bundle-version="9.3.0";resolution:=optional,
25+
org.python.pydev;bundle-version="9.3.0";resolution:=optional,
26+
org.python.pydev.core;bundle-version="9.3.0";resolution:=optional,
27+
org.python.pydev.ast;bundle-version="9.3.0";resolution:=optional,
28+
org.python.pydev.debug;bundle-version="9.3.0";resolution:=optional,
2829
org.eclipse.cdt.core;bundle-version="5.9.1";resolution:=optional,
2930
org.eclipse.cdt.ui;bundle-version="5.9.0";resolution:=optional
3031
Bundle-RequiredExecutionEnvironment: JavaSE-21

GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/README.md

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# GhidraDev Eclipse Plugin
22
GhidraDev provides support for developing and debugging Ghidra scripts and modules in Eclipse.
33

4-
The information provided in this document is effective as of GhidraDev 4.0.0 and is subject to
4+
The information provided in this document is effective as of GhidraDev 5.0.0 and is subject to
55
change with future releases.
66

77
## Table of Contents
@@ -31,6 +31,9 @@ change with future releases.
3131
12. [Building](#building)
3232

3333
## Change History
34+
__5.0.0:__
35+
* Added support for PyGhidra.
36+
3437
__4.0.1:__
3538
* New Ghidra module projects now contain a default `README.md` file.
3639
* Fixed a bug that prevented an imported module source project from being discovered by Ghidra when
@@ -132,7 +135,7 @@ __1.0.1:__
132135
* Ghidra 11.2 or later
133136

134137
## Optional Requirements
135-
* PyDev 6.3.1 - 9.3.0 ([more info](#pydev-support))
138+
* PyDev 9.3.0 or later ([more info](#pydev-support))
136139
* Gradle - required version(s) specified by linked Ghidra release
137140
([more info](#export-ghidra-module-extension))
138141

@@ -268,7 +271,10 @@ Ghidra from Eclipse independent of a project is not supported.
268271

269272
## PyDev Support
270273
GhidraDev is able to integrate with PyDev to conveniently configure Python support into Ghidra
271-
script and module projects.
274+
script and module projects. GhidraDev supports both Jython and PyGhidra Python implementations.
275+
276+
__NOTE:__ PyDev discontinued Jython 2 support in version 10.0.0. If you want to use GhidraDev with
277+
Jython, you must use __PyDev 9.3.0__. The latest vesions of PyDev support PyGhidra.
272278

273279
### Installing PyDev
274280
From Eclipse:
@@ -293,13 +299,19 @@ GhidraDev can add Python support to a Ghidra project when:
293299
* Creating a new Ghidra script project
294300
* Linking a Ghidra installation to an existing Java project
295301

296-
In order for GhidraDev to add in Python support, PyDev must have a Jython interpreter configured.
297-
GhidraDev will present a list of detected Jython interpreters that it found in PyDev's preferences.
298-
If no Jython interpreters were found, one can be added from GhidraDev by clicking the `+` icon.
299-
When the `+` icon is clicked, GhidraDev will attempt to find the Jython interpreter bundled with the
300-
selected Ghidra installation and automatically configure PyDev to use it. If for some reason
301-
GhidraDev was unable to find a Jython interpreter in the Ghidra installation, one will have to be
302-
added manually in the PyDev preferences.
302+
In order for GhidraDev to add in Python support, PyDev must have a PyGhidra or Jython interpreter
303+
configured. GhidraDev will present a list of detected PyGhidra/Jython interpreters that it found in
304+
PyDev's preferences. If no interpreters were found, one can be added from GhidraDev by clicking
305+
the `+` icons.
306+
307+
When the Jython `+` icon is clicked, GhidraDev will attempt to find the Jython interpreter bundled
308+
with the selected Ghidra installation and automatically configure PyDev to use it. If for some
309+
reason GhidraDev was unable to find a Jython interpreter in the Ghidra installation, one will have
310+
to be added manually in the PyDev preferences.
311+
312+
When the PyGhidra `+` icon is clicked, GhidraDev will attempt to find the PyGhidra interpreter
313+
that was last used to launch PyGhidra. If it cannot find it, you will have to launch PyGhidra
314+
and try again.
303315

304316
## Upgrading
305317
GhidraDev is upgraded differently depending on how it was installed. If GhidraDev was
@@ -347,9 +359,6 @@ installation directory.
347359
to your Ghidra module project, which automatically happens when the project is created.
348360
Simply [relink](#link-ghidra) your Ghidra installation to the project, and your project will
349361
pick up any newly discovered Ghidra extensions.
350-
* __Why doesn't GhidraDev support PyDev 10.0 or later?__
351-
* PyDev dropped support for Python 2 in their 10.0 release. Ghidra currently does not support
352-
Python 3.
353362

354363
## Additional Resources
355364
For more information on the GhidraDev plugin and developing for Ghidra in an Eclipse environment,
@@ -358,14 +367,14 @@ at `<GhidraInstallDir>/docs/GhidraClass/Intermediate/Scripting.html`.
358367

359368
## Building
360369
GhidraDev is currently built from Eclipse and distributed with Ghidra manually. Ideally we will use
361-
Gradle one day, but we aren't there yet. We do rely on `gradle prepDev` to generate the Eclipse
362-
project and build GhidraDev's dependencies though.
370+
Gradle one day, but we aren't there yet. We do rely on Gradle to generate the Eclipse project and
371+
build GhidraDev's dependencies though.
363372

364373
__NOTE:__ Only "Eclipse for RCP and RAP Developers" has the ability to do the below instructions.
365374
The following instructions assume that you are using this version of Eclipse.
366375

367376
#### Importing GhidraDev Eclipse projects (they are deactivated by default):
368-
1. Run `gradle eclipse -PeclipsePDE`
377+
1. Run `gradle prepGhidraDev eclipse -PeclipsePDE`
369378
2. From Eclipse, `File -> Import -> General -> Existing Projects into Workspace`
370379
3. From the ghidra repo, import `Eclipse GhidraDevFeature` and `Eclipse GhidraDevPlugin`
371380

GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/build.gradle

+9-8
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ task pyDevUnpack(type:Copy) {
8181
!pyDevDestDir.exists()
8282
}
8383

84-
File depsFile = file("${DEPS_DIR}/GhidraDev/PyDev 6.3.1.zip")
85-
File binRepoFile = file("${BIN_REPO}/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/PyDev 6.3.1.zip")
84+
File depsFile = file("${DEPS_DIR}/GhidraDev/PyDev 9.3.0.zip")
85+
File binRepoFile = file("${BIN_REPO}/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/PyDev 9.3.0.zip")
8686

8787
// First check if the file is in the dependencies repo. If not, check in the bin repo.
8888
def pyDevZipTree = depsFile.exists() ? zipTree(depsFile) : zipTree(binRepoFile)
@@ -115,6 +115,13 @@ task cdtUnpack(type:Copy) {
115115
destinationDir cdtDestDir
116116
}
117117

118+
task prepGhidraDev {
119+
dependsOn("utilityJar")
120+
dependsOn("launchSupportJar")
121+
dependsOn("pyDevUnpack")
122+
dependsOn("cdtUnpack")
123+
}
124+
118125
// We do not currently build GhidraDev plugin at Ghidra build time so we must
119126
// copy the prebuilt zip file from the BIN_REPO
120127
rootProject.assembleDistribution {
@@ -129,9 +136,3 @@ rootProject.assembleMarkdownToHtml {
129136
into "Extensions/Eclipse/GhidraDev/"
130137
}
131138
}
132-
133-
// PrepDev dependencies
134-
rootProject.prepDev.dependsOn utilityJar
135-
rootProject.prepDev.dependsOn launchSupportJar
136-
rootProject.prepDev.dependsOn pyDevUnpack
137-
rootProject.prepDev.dependsOn cdtUnpack
Loading

GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/plugin.xml

+54
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,11 @@
378378
id="GhidraHeadlessLaunchConfigurationType"
379379
name="Ghidra Headless">
380380
</launchConfigurationType>
381+
<launchConfigurationType
382+
delegate="ghidradev.ghidraprojectcreator.launchers.PyGhidraLaunchDelegate"
383+
id="PyGhidraGuiLaunchConfigurationType"
384+
name="PyGhidra">
385+
</launchConfigurationType>
381386
</extension>
382387
<extension
383388
point="org.eclipse.debug.ui.launchConfigurationTypeImages">
@@ -391,6 +396,11 @@
391396
icon="icons/GhidraIcon16_bw.png"
392397
id="GhidraHeadlessLaunchConfigurationTypeImage">
393398
</launchConfigurationTypeImage>
399+
<launchConfigurationTypeImage
400+
configTypeID="PyGhidraGuiLaunchConfigurationType"
401+
icon="icons/python.png"
402+
id="PyGhidraGuiLaunchConfigurationTypeImage">
403+
</launchConfigurationTypeImage>
394404
</extension>
395405
<extension
396406
point="org.eclipse.debug.core.launchDelegates">
@@ -408,6 +418,13 @@
408418
name="Ghidra Headless"
409419
type="GhidraHeadlessLaunchConfigurationType">
410420
</launchDelegate>
421+
<launchDelegate
422+
delegate="ghidradev.ghidraprojectcreator.launchers.PyGhidraLaunchDelegate"
423+
id="PyGhidraGuiLaunchDelegate"
424+
modes="run, debug"
425+
name="PyGhidra GUI"
426+
type="PyGhidraGuiLaunchConfigurationType">
427+
</launchDelegate>
411428
</extension>
412429
<extension
413430
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
@@ -423,6 +440,12 @@
423440
id="GhidraHeadlessLaunchConfigurationTabGroup"
424441
type="GhidraHeadlessLaunchConfigurationType">
425442
</launchConfigurationTabGroup>
443+
<launchConfigurationTabGroup
444+
class="org.python.pydev.debug.ui.PythonTabGroup"
445+
description="Run and debug PyGhidra modules and scripts"
446+
id="PyGhidraGuiLaunchConfigurationTabGroup"
447+
type="PyGhidraGuiLaunchConfigurationType">
448+
</launchConfigurationTabGroup>
426449
</extension>
427450
<extension
428451
point="org.eclipse.debug.ui.launchShortcuts">
@@ -474,6 +497,30 @@
474497
</enablement>
475498
</contextualLaunch>
476499
</shortcut>
500+
<shortcut
501+
class="ghidradev.ghidraprojectcreator.launchers.PyGhidraGuiLaunchShortcut"
502+
icon="icons/python.png"
503+
id="PyGhidraGuiLaunchShortcut"
504+
label="PyGhidra"
505+
modes="run, debug">
506+
<contextualLaunch>
507+
<enablement>
508+
<with
509+
variable="selection">
510+
<count
511+
value="1">
512+
</count>
513+
<iterate
514+
ifEmpty="false">
515+
<test
516+
property="ghidradev.ghidraprojectcreator.testers.isPyGhidraProject"
517+
value="true">
518+
</test>
519+
</iterate>
520+
</with>
521+
</enablement>
522+
</contextualLaunch>
523+
</shortcut>
477524
</extension>
478525
<extension
479526
point="org.eclipse.core.expressions.propertyTesters">
@@ -505,6 +552,13 @@
505552
properties="isGhidraModuleProject"
506553
type="java.lang.Object">
507554
</propertyTester>
555+
<propertyTester
556+
class="ghidradev.ghidraprojectcreator.testers.PyGhidraProjectPropertyTester"
557+
id="PyGhidraProjectPropertyTester"
558+
namespace="ghidradev.ghidraprojectcreator.testers"
559+
properties="isPyGhidraProject"
560+
type="java.lang.Object">
561+
</propertyTester>
508562
</extension>
509563

510564
</plugin>

0 commit comments

Comments
 (0)