mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-18 10:18:40 +08:00
GP-6659: Adding PyGhidra headless launcher to GhidraDev
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<feature
|
||||
id="ghidra.ghidradev"
|
||||
label="GhidraDev"
|
||||
version="5.0.1.qualifier"
|
||||
version="5.1.0.qualifier"
|
||||
provider-name="Ghidra">
|
||||
|
||||
<description>
|
||||
|
||||
@@ -172,14 +172,13 @@
|
||||
<setEntry value="com.python.pydev.analysis*9.3.0.202203051235@default:default"/>
|
||||
<setEntry value="com.python.pydev.debug*9.3.0.202203051235@default:default"/>
|
||||
<setEntry value="com.python.pydev.refactoring*9.3.0.202203051235@default:default"/>
|
||||
<setEntry value="com.sun.el.javax.el@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="jakarta.annotation-api@default:default"/>
|
||||
<setEntry value="jakarta.annotation-api*1.3.5@default:default"/>
|
||||
<setEntry value="jakarta.annotation-api*2.1.1@default:default"/>
|
||||
<setEntry value="jakarta.inject.jakarta.inject-api*1.0.5@default:default"/>
|
||||
<setEntry value="jakarta.inject.jakarta.inject-api*2.0.1@default:default"/>
|
||||
<setEntry value="jakarta.servlet-api@default:default"/>
|
||||
<setEntry value="javax.annotation@default:default"/>
|
||||
<setEntry value="jaxen@default:default"/>
|
||||
<setEntry value="org.apache.aries.spifly.dynamic.bundle@default:default"/>
|
||||
<setEntry value="org.apache.batik.constants@default:default"/>
|
||||
@@ -189,8 +188,8 @@
|
||||
<setEntry value="org.apache.commons.cli@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-codec@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-io@default:default"/>
|
||||
<setEntry value="org.apache.commons.commons-logging@default:default"/>
|
||||
<setEntry value="org.apache.commons.lang3@default:default"/>
|
||||
<setEntry value="org.apache.commons.logging@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.command@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.runtime@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.shell@default:default"/>
|
||||
@@ -202,7 +201,7 @@
|
||||
<setEntry value="org.apache.xml.resolver@default:default"/>
|
||||
<setEntry value="org.apache.xml.serializer@default:default"/>
|
||||
<setEntry value="org.apache.xmlgraphics@default:default"/>
|
||||
<setEntry value="org.commonmark-gfm-tables@default:default"/>
|
||||
<setEntry value="org.commonmark.ext-gfm-tables@default:default"/>
|
||||
<setEntry value="org.commonmark@default:default"/>
|
||||
<setEntry value="org.eclipse.ant.core@default:default"/>
|
||||
<setEntry value="org.eclipse.buildship.compat@default:default"/>
|
||||
@@ -310,12 +309,12 @@
|
||||
<setEntry value="org.eclipse.jdt.launching@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.jem.util@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee.webapp@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee10.servlet@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee10.webapp@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee8.security@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee8.server@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee8.servlet@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.ee@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.http@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.io@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.security@default:default"/>
|
||||
@@ -350,7 +349,7 @@
|
||||
<setEntry value="org.eclipse.search.core@default:default"/>
|
||||
<setEntry value="org.eclipse.search@default:default"/>
|
||||
<setEntry value="org.eclipse.swt.cocoa.macosx.aarch64@default:false"/>
|
||||
<setEntry value="org.eclipse.swt.svg@default:default"/>
|
||||
<setEntry value="org.eclipse.swt.svg@default:false"/>
|
||||
<setEntry value="org.eclipse.swt@default:default"/>
|
||||
<setEntry value="org.eclipse.team.core@default:default"/>
|
||||
<setEntry value="org.eclipse.team.ui@default:default"/>
|
||||
@@ -392,8 +391,6 @@
|
||||
<setEntry value="org.hamcrest@default:default"/>
|
||||
<setEntry value="org.jdom2@default:default"/>
|
||||
<setEntry value="org.junit@default:default"/>
|
||||
<setEntry value="org.mortbay.jasper.apache-el@default:default"/>
|
||||
<setEntry value="org.mortbay.jasper.apache-jsp@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.commons@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.tree.analysis@default:default"/>
|
||||
<setEntry value="org.objectweb.asm.tree@default:default"/>
|
||||
|
||||
@@ -3,7 +3,7 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: GhidraDev
|
||||
Bundle-SymbolicName: ghidra.ghidradev;singleton:=true
|
||||
Bundle-Version: 5.0.1.qualifier
|
||||
Bundle-Version: 5.1.0.qualifier
|
||||
Bundle-Activator: ghidradev.Activator
|
||||
Require-Bundle: org.eclipse.ant.core;bundle-version="3.7.200",
|
||||
org.eclipse.buildship.core;bundle-version="3.1.8",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# GhidraDev Eclipse Plugin
|
||||
GhidraDev provides support for developing and debugging Ghidra scripts and modules in Eclipse.
|
||||
|
||||
The information provided in this document is effective as of GhidraDev 5.0.1 and is subject to
|
||||
The information provided in this document is effective as of GhidraDev 5.1.0 and is subject to
|
||||
change with future releases.
|
||||
|
||||
## Table of Contents
|
||||
@@ -31,6 +31,9 @@ change with future releases.
|
||||
12. [Building](#building)
|
||||
|
||||
## Change History
|
||||
__5.1.0:__
|
||||
* Added a PyGhidra Headless run configuration
|
||||
|
||||
__5.0.1:__
|
||||
* Fixed a bug that prevented Ghidra from discovering the Ghidra module project when launched with
|
||||
the PyGhidra run configuration.
|
||||
@@ -319,8 +322,16 @@ that was last used to launch PyGhidra. If it cannot find it, you will have to l
|
||||
and try again.
|
||||
|
||||
### Launching and Debugging PyGhidra
|
||||
GhidraDev can interface with PyDev to provide a __PyGhidra__ run configuration that is capable of
|
||||
launching PyGhidra in both GUI mode and GUI debug mode.
|
||||
When PyDev is installed, GhidraDev introduces two new run configurations to Eclipse which are
|
||||
capable of launching the installation of Ghidra (in PyGhidra mode) that an Eclipse Ghidra project is
|
||||
linked to:
|
||||
* __PyGhidra:__ Launches the PyGhidra GUI.
|
||||
* __PyGhidra Headless:__ Launches PyGhidra in headless mode. By default, this run configuration will
|
||||
not have any program arguments associated with it, which are required to tell headless PyGhidra
|
||||
what project to open, what scripts to run, etc. Newly created `PyGhidra Headless` run
|
||||
configurations will have to be modified with the desired headless program arguments. For more
|
||||
information on headless command line arguments, see
|
||||
`<GhidraInstallDir>/support/analyzeHeadlessREADME.html`.
|
||||
|
||||
## Upgrading
|
||||
GhidraDev is upgraded differently depending on how it was installed. If GhidraDev was
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 517 B |
@@ -383,6 +383,11 @@
|
||||
id="PyGhidraGuiLaunchConfigurationType"
|
||||
name="PyGhidra">
|
||||
</launchConfigurationType>
|
||||
<launchConfigurationType
|
||||
delegate="ghidradev.ghidraprojectcreator.launchers.PyGhidraLaunchDelegate"
|
||||
id="PyGhidraHeadlessLaunchConfigurationType"
|
||||
name="PyGhidra Headless">
|
||||
</launchConfigurationType>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTypeImages">
|
||||
@@ -401,6 +406,11 @@
|
||||
icon="icons/python.png"
|
||||
id="PyGhidraGuiLaunchConfigurationTypeImage">
|
||||
</launchConfigurationTypeImage>
|
||||
<launchConfigurationTypeImage
|
||||
configTypeID="PyGhidraHeadlessLaunchConfigurationType"
|
||||
icon="icons/python_bw.png"
|
||||
id="PyGhidraHeadlessLaunchConfigurationTypeImage">
|
||||
</launchConfigurationTypeImage>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.core.launchDelegates">
|
||||
@@ -425,6 +435,13 @@
|
||||
name="PyGhidra GUI"
|
||||
type="PyGhidraGuiLaunchConfigurationType">
|
||||
</launchDelegate>
|
||||
<launchDelegate
|
||||
delegate="ghidradev.ghidraprojectcreator.launchers.PyGhidraLaunchDelegate"
|
||||
id="PyGhidraHeadlessLaunchDelegate"
|
||||
modes="run, debug"
|
||||
name="PyGhidra Headless"
|
||||
type="PyGhidraHeadlessLaunchConfigurationType">
|
||||
</launchDelegate>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
|
||||
@@ -441,11 +458,17 @@
|
||||
type="GhidraHeadlessLaunchConfigurationType">
|
||||
</launchConfigurationTabGroup>
|
||||
<launchConfigurationTabGroup
|
||||
class="org.python.pydev.debug.ui.PythonTabGroup"
|
||||
class="ghidradev.ghidraprojectcreator.launchers.PyGhidraLaunchTabGroup"
|
||||
description="Run and debug PyGhidra modules and scripts"
|
||||
id="PyGhidraGuiLaunchConfigurationTabGroup"
|
||||
type="PyGhidraGuiLaunchConfigurationType">
|
||||
</launchConfigurationTabGroup>
|
||||
<launchConfigurationTabGroup
|
||||
class="ghidradev.ghidraprojectcreator.launchers.PyGhidraLaunchTabGroup"
|
||||
description="Run and debug PyGhidra modules and scripts in headless mode"
|
||||
id="PyGhidraHeadlessLaunchConfigurationTabGroup"
|
||||
type="PyGhidraHeadlessLaunchConfigurationType">
|
||||
</launchConfigurationTabGroup>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchShortcuts">
|
||||
@@ -521,6 +544,30 @@
|
||||
</enablement>
|
||||
</contextualLaunch>
|
||||
</shortcut>
|
||||
<shortcut
|
||||
class="ghidradev.ghidraprojectcreator.launchers.PyGhidraHeadlessLaunchShortcut"
|
||||
icon="icons/python_bw.png"
|
||||
id="PyGhidraHeadlessLaunchShortcut"
|
||||
label="PyGhidra Headless"
|
||||
modes="run, debug">
|
||||
<contextualLaunch>
|
||||
<enablement>
|
||||
<with
|
||||
variable="selection">
|
||||
<count
|
||||
value="1">
|
||||
</count>
|
||||
<iterate
|
||||
ifEmpty="false">
|
||||
<test
|
||||
property="ghidradev.ghidraprojectcreator.testers.isPyGhidraProject"
|
||||
value="true">
|
||||
</test>
|
||||
</iterate>
|
||||
</with>
|
||||
</enablement>
|
||||
</contextualLaunch>
|
||||
</shortcut>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.core.expressions.propertyTesters">
|
||||
|
||||
+1
-5
@@ -90,11 +90,7 @@ public class GhidraLaunchDelegate extends JavaLaunchDelegate {
|
||||
programArgs += " " + customProgramArgs;
|
||||
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, programArgs);
|
||||
if (isHeadless && customProgramArgs.isEmpty()) {
|
||||
EclipseMessageUtils.showInfoDialog("Ghidra Run Configuration",
|
||||
"Headless launch is being performed without any command line arguments!\n\n" +
|
||||
"Edit the \"" + configuration.getName() +
|
||||
"\" run configuration's program arguments to customize headless behavior. " +
|
||||
"See support/analyzeHeadlessREADME.html for more information.");
|
||||
GhidraLaunchUtils.notifyAboutHeadlessWithNoArgs(configuration);
|
||||
}
|
||||
|
||||
// Set VM arguments
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import ghidradev.ghidraprojectcreator.utils.GhidraLaunchUtils;
|
||||
/**
|
||||
* The PyGhidra GUI launch shortcut actions.
|
||||
*
|
||||
* @see AbstractGhidraLaunchShortcut
|
||||
* @see AbstractPyGhidraLaunchShortcut
|
||||
*/
|
||||
public class PyGhidraGuiLaunchShortcut extends AbstractPyGhidraLaunchShortcut {
|
||||
|
||||
@@ -28,6 +28,6 @@ public class PyGhidraGuiLaunchShortcut extends AbstractPyGhidraLaunchShortcut {
|
||||
* Creates a new PyGhidra GUI launch shortcut.
|
||||
*/
|
||||
public PyGhidraGuiLaunchShortcut() {
|
||||
super(GhidraLaunchUtils.PYGHIDRA_GUI_LAUNCH, " GUI");
|
||||
super(GhidraLaunchUtils.PYGHIDRA_GUI_LAUNCH, " (PyGhidra)");
|
||||
}
|
||||
}
|
||||
|
||||
+33
@@ -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.
|
||||
*/
|
||||
package ghidradev.ghidraprojectcreator.launchers;
|
||||
|
||||
import ghidradev.ghidraprojectcreator.utils.GhidraLaunchUtils;
|
||||
|
||||
/**
|
||||
* The PyGhidra Headless launch shortcut actions.
|
||||
*
|
||||
* @see AbstractPyGhidraLaunchShortcut
|
||||
*/
|
||||
public class PyGhidraHeadlessLaunchShortcut extends AbstractPyGhidraLaunchShortcut {
|
||||
|
||||
/**
|
||||
* Creates a new PyGhidra Headless launch shortcut.
|
||||
*/
|
||||
public PyGhidraHeadlessLaunchShortcut() {
|
||||
super(GhidraLaunchUtils.PYGHIDRA_HEADLESS_LAUNCH, " (PyGhidra Headless)");
|
||||
}
|
||||
}
|
||||
+40
-9
@@ -37,8 +37,7 @@ import org.python.pydev.debug.ui.launching.RegularLaunchConfigurationDelegate;
|
||||
|
||||
import ghidra.launch.AppConfig;
|
||||
import ghidradev.EclipseMessageUtils;
|
||||
import ghidradev.ghidraprojectcreator.utils.GhidraProjectUtils;
|
||||
import ghidradev.ghidraprojectcreator.utils.PyDevUtils;
|
||||
import ghidradev.ghidraprojectcreator.utils.*;
|
||||
|
||||
/**
|
||||
* The PyGhidra Launch delegate handles the final launch of PyGhidra.
|
||||
@@ -51,6 +50,9 @@ public class PyGhidraLaunchDelegate extends RegularLaunchConfigurationDelegate {
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
try {
|
||||
boolean isHeadless = configuration.getType()
|
||||
.getIdentifier()
|
||||
.equals(GhidraLaunchUtils.PYGHIDRA_HEADLESS_LAUNCH);
|
||||
ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy();
|
||||
|
||||
// Get project
|
||||
@@ -82,16 +84,45 @@ public class PyGhidraLaunchDelegate extends RegularLaunchConfigurationDelegate {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which module to call
|
||||
String module = "pyghidra";
|
||||
if (isHeadless) {
|
||||
module += "/ghidra_launch.py";
|
||||
}
|
||||
|
||||
// Set program location
|
||||
wc.setAttribute(PyDevUtils.getAttrLocation(),
|
||||
"${workspace_loc:%s/Ghidra/Ghidra/Features/PyGhidra/pypkg/src/pyghidra}"
|
||||
.formatted(project.getName()));
|
||||
"${workspace_loc:%s/Ghidra/Ghidra/Features/PyGhidra/pypkg/src/%s}"
|
||||
.formatted(project.getName(), module));
|
||||
|
||||
// Set VM arguments
|
||||
String vmArgs =
|
||||
" " + configuration.getAttribute(GhidraLaunchUtils.ATTR_VM_ARGUMENTS, "").trim();
|
||||
vmArgs += " -Dghidra.external.modules=\"%s%s%s\"".formatted(
|
||||
javaProject.getProject().getLocation(), File.pathSeparator,
|
||||
GhidraProjectUtils.getProjectDependencyDirs(javaProject));
|
||||
File pyDevSrcDir = PyDevUtils.getPyDevSrcDir();
|
||||
if (pyDevSrcDir != null) {
|
||||
vmArgs += " " + "-Declipse.pysrc.dir=\"" + pyDevSrcDir + "\"";
|
||||
}
|
||||
|
||||
// Set program arguments
|
||||
wc.setAttribute(PyDevUtils.getAttrProgramArguments(),
|
||||
"-v -g -D ghidra.external.modules=\"%s%s%s\"".formatted(
|
||||
javaProject.getProject().getLocation(), File.pathSeparator,
|
||||
GhidraProjectUtils.getProjectDependencyDirs(javaProject)));
|
||||
String customProgramArgs =
|
||||
configuration.getAttribute(GhidraLaunchUtils.ATTR_PROGAM_ARGUMENTS, "").trim();
|
||||
StringBuilder args = new StringBuilder();
|
||||
if (isHeadless) {
|
||||
args.append("ghidra.app.util.headless.AnalyzeHeadless ");
|
||||
}
|
||||
else {
|
||||
args.append("-v ");
|
||||
args.append("-g ");
|
||||
}
|
||||
args.append(vmArgs + " ");
|
||||
args.append(customProgramArgs);
|
||||
wc.setAttribute(PyDevUtils.getAttrProgramArguments(), args.toString());
|
||||
if (isHeadless && customProgramArgs.isEmpty()) {
|
||||
GhidraLaunchUtils.notifyAboutHeadlessWithNoArgs(configuration);
|
||||
}
|
||||
|
||||
// Set Python interpreter
|
||||
String interpreterName = PyDevUtils.getInterpreterName(project);
|
||||
@@ -100,7 +131,7 @@ public class PyGhidraLaunchDelegate extends RegularLaunchConfigurationDelegate {
|
||||
|
||||
// Set environment variables
|
||||
Map<String, String> env = new HashMap<>();
|
||||
//env.put("GHIDRA_INSTALL_DIR", "${project_loc:/%s/Ghidra}".formatted(project.getName()));
|
||||
env = wc.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, env);
|
||||
env.put("GHIDRA_INSTALL_DIR",
|
||||
"${resource_loc:/%s/Ghidra}".formatted(project.getName()));
|
||||
env.put("JAVA_HOME_OVERRIDE", "${ee_home:JavaSE-%s}".formatted(javaComplianceLevel));
|
||||
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidradev.ghidraprojectcreator.launchers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.ui.*;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
import org.python.pydev.debug.ui.*;
|
||||
|
||||
import ghidradev.EclipseMessageUtils;
|
||||
import ghidradev.ghidraprojectcreator.utils.GhidraLaunchUtils;
|
||||
|
||||
/**
|
||||
* The PyGhidra launcher tab group with default values needed for running/debugging
|
||||
* PyGhidra. Some Python tabs are hidden here because we don't want the user changing their
|
||||
* properties. These properties are set in {@link PyGhidraLaunchDelegate}, which occurs right before
|
||||
* the launch.
|
||||
*/
|
||||
public class PyGhidraLaunchTabGroup extends PythonTabGroup {
|
||||
|
||||
@Override
|
||||
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
|
||||
|
||||
// Create the tabs
|
||||
List<ILaunchConfigurationTab> tabs = new ArrayList<>();
|
||||
tabs.add(getMainModuleTab());
|
||||
tabs.add(getUserDefinedArgumentsTab());
|
||||
tabs.add(getInterpreterTab());
|
||||
tabs.add(new EnvironmentTab());
|
||||
tabs.add(getCommonTab());
|
||||
|
||||
// Set the tabs
|
||||
setTabs(tabs.toArray(new ILaunchConfigurationTab[tabs.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link MainModuleTab} to use, with PyGhidra's main module pre-configured in.
|
||||
*
|
||||
* @return The {@link MainModuleTab} to use, with Ghidra's main method pre-configured in.
|
||||
*/
|
||||
private MainModuleTab getMainModuleTab() {
|
||||
return new MainModuleTab() {
|
||||
@Override
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
GhidraLaunchUtils.setMainTypeName(wc);
|
||||
super.initializeFrom(wc.doSave());
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to initialize the Python main module tab.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user-defined arguments to use. These will be appended to PyGhidra's required
|
||||
* launch arguments, which are hidden from the tab group.
|
||||
*
|
||||
* @return The user-defined arguments to use.
|
||||
*/
|
||||
private AbstractLaunchConfigurationTab getUserDefinedArgumentsTab() {
|
||||
return new AbstractLaunchConfigurationTab() {
|
||||
|
||||
private Text programArgsText;
|
||||
private Text vmArgsText;
|
||||
|
||||
@Override
|
||||
public void createControl(Composite parent) {
|
||||
Composite container = new Composite(parent, SWT.NONE);
|
||||
container.setLayout(new GridLayout(1, true));
|
||||
GridData gd = new GridData(GridData.FILL_BOTH);
|
||||
container.setLayoutData(gd);
|
||||
|
||||
// Program arguments
|
||||
Group group = new Group(container, SWT.NONE);
|
||||
group.setLayout(new GridLayout());
|
||||
group.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||
group.setText("Program arguments:");
|
||||
programArgsText = new Text(group, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
|
||||
gd = new GridData(GridData.FILL_BOTH);
|
||||
gd.heightHint = 40;
|
||||
gd.widthHint = 100;
|
||||
programArgsText.setLayoutData(gd);
|
||||
programArgsText.addModifyListener(evt -> scheduleUpdateJob());
|
||||
|
||||
// VM arguments
|
||||
group = new Group(container, SWT.NONE);
|
||||
group.setLayout(new GridLayout());
|
||||
group.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||
group.setText("VM arguments (appended to arguments defined in launch.properties):");
|
||||
vmArgsText = new Text(group, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
|
||||
gd = new GridData(GridData.FILL_BOTH);
|
||||
gd.heightHint = 40;
|
||||
gd.widthHint = 100;
|
||||
vmArgsText.setLayoutData(gd);
|
||||
vmArgsText.addModifyListener(evt -> scheduleUpdateJob());
|
||||
|
||||
setControl(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
wc.setAttribute(GhidraLaunchUtils.ATTR_PROGAM_ARGUMENTS, "");
|
||||
wc.setAttribute(GhidraLaunchUtils.ATTR_VM_ARGUMENTS, "");
|
||||
wc.doSave();
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to set argument defaults.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
try {
|
||||
programArgsText.setText(
|
||||
config.getAttribute(GhidraLaunchUtils.ATTR_PROGAM_ARGUMENTS, ""));
|
||||
vmArgsText.setText(
|
||||
config.getAttribute(GhidraLaunchUtils.ATTR_VM_ARGUMENTS, ""));
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to initialize the arguments.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performApply(ILaunchConfigurationWorkingCopy config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
wc.setAttribute(GhidraLaunchUtils.ATTR_PROGAM_ARGUMENTS,
|
||||
programArgsText.getText());
|
||||
wc.setAttribute(GhidraLaunchUtils.ATTR_VM_ARGUMENTS, vmArgsText.getText());
|
||||
wc.doSave();
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to apply the arguments.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Arguments";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link InterpreterTab} to use
|
||||
*
|
||||
* @return The {@link InterpreterTab} to use
|
||||
*/
|
||||
private InterpreterTab getInterpreterTab() {
|
||||
return new InterpreterTab() {
|
||||
@Override
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
GhidraLaunchUtils.setClasspath(wc);
|
||||
super.initializeFrom(wc.doSave());
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to initialize the Python interpreter tab.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link CommonTab} to use, with the new launch configuration added to the favorites.
|
||||
*
|
||||
* @return The {@link CommonTab} to use, with the new launch configuration added to the
|
||||
* favorites.
|
||||
*/
|
||||
private CommonTab getCommonTab() {
|
||||
return new CommonTab() {
|
||||
@Override
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
GhidraLaunchUtils.setFavorites(wc);
|
||||
super.initializeFrom(wc.doSave());
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to initialize the common tab.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+21
@@ -30,6 +30,7 @@ import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.launching.*;
|
||||
|
||||
import ghidra.Ghidra;
|
||||
import ghidradev.EclipseMessageUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for working with Ghidra launchers in Eclipse.
|
||||
@@ -55,6 +56,12 @@ public class GhidraLaunchUtils {
|
||||
*/
|
||||
public static final String PYGHIDRA_GUI_LAUNCH = "PyGhidraGuiLaunchConfigurationType";
|
||||
|
||||
/**
|
||||
* Launch configuration ID for a PyGhidra Headless launch. Must match corresponding value in
|
||||
* plugin.xml.
|
||||
*/
|
||||
public static final String PYGHIDRA_HEADLESS_LAUNCH = "PyGhidraHeadlessLaunchConfigurationType";
|
||||
|
||||
/**
|
||||
* Program arguments that will get passed to the launched Ghidra. These will be appended
|
||||
* to the required program arguments that are required to launch Ghidra, which are hidden
|
||||
@@ -277,4 +284,18 @@ public class GhidraLaunchUtils {
|
||||
runHistory.addFavorite(launchConfig);
|
||||
debugHistory.addFavorite(launchConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the user that a headless launch is being performed without any command line
|
||||
* arguments
|
||||
*
|
||||
* @param configuration The headless launch configuration
|
||||
*/
|
||||
public static void notifyAboutHeadlessWithNoArgs(ILaunchConfiguration configuration) {
|
||||
EclipseMessageUtils.showInfoDialog("Ghidra Run Configuration",
|
||||
"Headless launch is being performed without any command line arguments!\n\n" +
|
||||
"Edit the \"" + configuration.getName() +
|
||||
"\" run configuration's program arguments to customize headless behavior. " +
|
||||
"See support/analyzeHeadlessREADME.html for more information.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ GhidraDevPlugin/icons/brick_add.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk i
|
||||
GhidraDevPlugin/icons/brick_go.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
GhidraDevPlugin/icons/folder_link.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
GhidraDevPlugin/icons/python.png||GHIDRA||||END|
|
||||
GhidraDevPlugin/icons/python_bw.png||GHIDRA||||END|
|
||||
GhidraDevPlugin/icons/script_add.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
GhidraDevPlugin/icons/script_code_red.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
GhidraDevPlugin/plugin.xml||GHIDRA||||END|
|
||||
|
||||
Reference in New Issue
Block a user