mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-10 06:02:09 +00:00
GP-707: GhidraDev updates
- New wizard to import a module source dir - Ghidra won't launch if build dir is present - Better validation when exporting extension
This commit is contained in:
parent
fc0e3e1b6f
commit
91cb801521
@ -163,19 +163,19 @@
|
||||
<setEntry value="ch.qos.logback.classic@default:default"/>
|
||||
<setEntry value="ch.qos.logback.core@default:default"/>
|
||||
<setEntry value="com.google.gson@default:default"/>
|
||||
<setEntry value="com.google.guava*30.1.0.v20221112-0806@default:default"/>
|
||||
<setEntry value="com.google.guava*32.1.2.jre@default:default"/>
|
||||
<setEntry value="com.google.guava.failureaccess@default:default"/>
|
||||
<setEntry value="com.google.guava@default:default"/>
|
||||
<setEntry value="com.ibm.icu@default:default"/>
|
||||
<setEntry value="com.python.pydev.analysis@default:default"/>
|
||||
<setEntry value="com.python.pydev.debug@default:default"/>
|
||||
<setEntry value="com.python.pydev.refactoring@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="jakarta.servlet-api*4.0.0@default:default"/>
|
||||
<setEntry value="jakarta.servlet-api*5.0.0@default:default"/>
|
||||
<setEntry value="javax.annotation@default:default"/>
|
||||
<setEntry value="javax.inject@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.xml@default:default"/>
|
||||
<setEntry value="jaxen@default:default"/>
|
||||
<setEntry value="org.apache.aries.spifly.dynamic.bundle@default:default"/>
|
||||
@ -184,10 +184,10 @@
|
||||
<setEntry value="org.apache.batik.i18n@default:default"/>
|
||||
<setEntry value="org.apache.batik.util@default:default"/>
|
||||
<setEntry value="org.apache.commons.cli@default:default"/>
|
||||
<setEntry value="org.apache.commons.codec@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.jxpath@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"/>
|
||||
@ -204,9 +204,8 @@
|
||||
<setEntry value="org.eclipse.buildship.compat@default:default"/>
|
||||
<setEntry value="org.eclipse.buildship.core@default:default"/>
|
||||
<setEntry value="org.eclipse.buildship.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.cdt.core.macosx*5.3.0.201502131403@default:default"/>
|
||||
<setEntry value="org.eclipse.cdt.core.native*5.7.0.201502131403@default:default"/>
|
||||
<setEntry value="org.eclipse.cdt.core.win32*5.4.0.201502131403@default:false"/>
|
||||
<setEntry value="org.eclipse.cdt.core.win32.x86_64*5.3.0.201502131403@default:false"/>
|
||||
<setEntry value="org.eclipse.cdt.core@default:default"/>
|
||||
<setEntry value="org.eclipse.cdt.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.compare.core@default:default"/>
|
||||
@ -220,13 +219,10 @@
|
||||
<setEntry value="org.eclipse.core.expressions@default:default"/>
|
||||
<setEntry value="org.eclipse.core.externaltools@default:default"/>
|
||||
<setEntry value="org.eclipse.core.filebuffers@default:default"/>
|
||||
<setEntry value="org.eclipse.core.filesystem.win32.x86_64@default:false"/>
|
||||
<setEntry value="org.eclipse.core.filesystem.macosx@default:default"/>
|
||||
<setEntry value="org.eclipse.core.filesystem@default:default"/>
|
||||
<setEntry value="org.eclipse.core.jobs@default:default"/>
|
||||
<setEntry value="org.eclipse.core.net.win32.x86_64@default:false"/>
|
||||
<setEntry value="org.eclipse.core.net.win32@default:false"/>
|
||||
<setEntry value="org.eclipse.core.net@default:default"/>
|
||||
<setEntry value="org.eclipse.core.resources.win32.x86_64@default:false"/>
|
||||
<setEntry value="org.eclipse.core.resources@default:default"/>
|
||||
<setEntry value="org.eclipse.core.runtime@default:true"/>
|
||||
<setEntry value="org.eclipse.core.variables@default:default"/>
|
||||
@ -250,9 +246,9 @@
|
||||
<setEntry value="org.eclipse.e4.ui.model.workbench@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.progress@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.services@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.swt.win32@default:false"/>
|
||||
<setEntry value="org.eclipse.e4.ui.widgets@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.workbench.addons.swt@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.workbench.renderers.swt.cocoa@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.workbench.renderers.swt@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.workbench.swt@default:default"/>
|
||||
<setEntry value="org.eclipse.e4.ui.workbench3@default:default"/>
|
||||
@ -289,15 +285,15 @@
|
||||
<setEntry value="org.eclipse.equinox.p2.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.preferences@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.registry@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.security.macosx@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.security.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.security.win32.x86_64@default:false"/>
|
||||
<setEntry value="org.eclipse.equinox.security@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.simpleconfigurator.manipulator@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.simpleconfigurator@1:true"/>
|
||||
<setEntry value="org.eclipse.help.base@default:default"/>
|
||||
<setEntry value="org.eclipse.help.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.help@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.annotation*2.2.700.v20220826-1026@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.annotation*2.2.800.v20231029-1039@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.core.compiler.batch@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.core.manipulation@default:default"/>
|
||||
<setEntry value="org.eclipse.jdt.core@default:default"/>
|
||||
@ -309,14 +305,18 @@
|
||||
<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.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.ee8.webapp@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"/>
|
||||
<setEntry value="org.eclipse.jetty.server@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.servlet@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.servlet-api@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.session@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.util.ajax@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.util@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.webapp@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.xml@default:default"/>
|
||||
<setEntry value="org.eclipse.jface.databinding@default:default"/>
|
||||
<setEntry value="org.eclipse.jface.notifications@default:default"/>
|
||||
@ -324,30 +324,33 @@
|
||||
<setEntry value="org.eclipse.jface@default:default"/>
|
||||
<setEntry value="org.eclipse.ltk.core.refactoring@default:default"/>
|
||||
<setEntry value="org.eclipse.ltk.ui.refactoring@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.catalog@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.catalog@default:false"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.common@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.descriptor@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.maven-artifact-transfer@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.descriptor@default:false"/>
|
||||
<setEntry value="org.eclipse.m2e.archetype.maven-artifact-transfer@default:false"/>
|
||||
<setEntry value="org.eclipse.m2e.core.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.core@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.logback@default:false"/>
|
||||
<setEntry value="org.eclipse.m2e.maven.runtime@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.model.edit@default:default"/>
|
||||
<setEntry value="org.eclipse.m2e.workspace.cli@default:default"/>
|
||||
<setEntry value="org.eclipse.orbit.xml-apis-ext@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi.compatibility.state@default:false"/>
|
||||
<setEntry value="org.eclipse.osgi.services@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi.util@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi@-1:true"/>
|
||||
<setEntry value="org.eclipse.platform@default:default"/>
|
||||
<setEntry value="org.eclipse.rap.tools.launch.rwt@default:default"/>
|
||||
<setEntry value="org.eclipse.search.core@default:default"/>
|
||||
<setEntry value="org.eclipse.search@default:default"/>
|
||||
<setEntry value="org.eclipse.swt.win32.win32.x86_64@default:false"/>
|
||||
<setEntry value="org.eclipse.swt.cocoa.macosx.aarch64@default:default"/>
|
||||
<setEntry value="org.eclipse.swt@default:default"/>
|
||||
<setEntry value="org.eclipse.team.core@default:default"/>
|
||||
<setEntry value="org.eclipse.team.ui@default:default"/>
|
||||
<setEntry value="org.eclipse.text@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.browser@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.cheatsheets@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.cocoa@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.console@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.editors@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.forms@default:default"/>
|
||||
@ -361,7 +364,6 @@
|
||||
<setEntry value="org.eclipse.ui.views.log@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.views.properties.tabbed@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.views@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.win32@default:false"/>
|
||||
<setEntry value="org.eclipse.ui.workbench.texteditor@default:default"/>
|
||||
<setEntry value="org.eclipse.ui.workbench@default:default"/>
|
||||
<setEntry value="org.eclipse.ui@default:default"/>
|
||||
@ -421,16 +423,12 @@
|
||||
<setEntry value="org.sat4j.core@default:default"/>
|
||||
<setEntry value="org.sat4j.pb@default:default"/>
|
||||
<setEntry value="org.tukaani.xz@default:default"/>
|
||||
<setEntry value="org.w3c.css.sac@default:default"/>
|
||||
<setEntry value="org.w3c.dom.events@default:default"/>
|
||||
<setEntry value="org.w3c.dom.smil@default:default"/>
|
||||
<setEntry value="org.w3c.dom.svg@default:default"/>
|
||||
<setEntry value="slf4j.api@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="ghidra.ghidradev@default:default"/>
|
||||
</setAttribute>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<booleanAttribute key="show_selected_only" value="true"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfig" value="true"/>
|
||||
|
@ -36,6 +36,7 @@ change with future releases.</p>
|
||||
<li><a href="#NewGhidraScript">New Ghidra Script</a></li>
|
||||
<li><a href="#NewGhidraScriptProject">New Ghidra Script Project</a></li>
|
||||
<li><a href="#NewGhidraModuleProject">New Ghidra Module Project</a></li>
|
||||
<li><a href="#ImportGhidraModuleSource">Import Ghidra Module Source</a></li>
|
||||
<li><a href="#ExportGhidraModuleExtension">Export Ghidra Module Extension</a></li>
|
||||
<li><a href="#Preferences">Preferences</a></li>
|
||||
<li><a href="#LinkGhidra">Link Ghidra</a></li>
|
||||
@ -59,6 +60,14 @@ change with future releases.</p>
|
||||
GhidraDev has been upgraded to be compatible with Ghidra 11.1 and later. Older versions of
|
||||
GhidraDev will report an error when trying to link against Ghidra 11.1 or later.
|
||||
</li>
|
||||
<li>
|
||||
GhidraDev now supports importing a Ghidra module source directory. This will work best
|
||||
with Ghidra module projects created from Ghidra 11.1 or later.
|
||||
</li>
|
||||
<li>
|
||||
GhidraDev will now fail to launch Ghidra if a top-level <i>build</i> directory is detected.
|
||||
Presence of this intermediate build artifact can cause Ghidra to have runtime/debugging issues.
|
||||
</li>
|
||||
</ul>
|
||||
<p><u><b>3.0.2</b>:</u>
|
||||
<ul>
|
||||
@ -243,6 +252,13 @@ installed into Ghidra as an "extension".</p>
|
||||
project can be initialized with optional template source files that provide a good starting
|
||||
point for implementing advanced Ghidra features such as Analyzers, Plugins, Loaders, etc.
|
||||
</li>
|
||||
</ul>
|
||||
<li>Import</li>
|
||||
<ul>
|
||||
<li>
|
||||
<a name="ImportGhidraModuleSource"></a><b>Ghidra Module Source:</b> Opens a wizard that
|
||||
imports a Ghidra module source directory as a new Ghidra module project.
|
||||
</li>
|
||||
</ul>
|
||||
<li>Export</li>
|
||||
<ul>
|
||||
|
@ -9,6 +9,7 @@ Require-Bundle: org.eclipse.ant.core;bundle-version="3.6.200",
|
||||
org.eclipse.buildship.core;bundle-version="3.1.5",
|
||||
org.eclipse.core.expressions;bundle-version="3.8.100",
|
||||
org.eclipse.core.externaltools;bundle-version="1.2.100",
|
||||
org.eclipse.core.resources;bundle-version="3.16.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.24.0",
|
||||
org.eclipse.debug.ui;bundle-version="3.15.200",
|
||||
org.eclipse.jdt.core;bundle-version="3.28.0",
|
||||
|
@ -38,6 +38,23 @@
|
||||
project="true">
|
||||
</wizard>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.importWizards">
|
||||
<category
|
||||
id="GhidraCategory"
|
||||
name="Ghidra">
|
||||
</category>
|
||||
<wizard
|
||||
category="GhidraCategory"
|
||||
class="ghidradev.ghidraprojectcreator.wizards.ImportGhidraModuleSourceWizard"
|
||||
icon="icons/brick_add.png"
|
||||
id="ghidradev.ghidraprojectcreator.wizards.ImportGhidraModuleSourceWizard"
|
||||
name="Ghidra Module Source">
|
||||
<description>
|
||||
Imports a Ghidra module source directory to a new project.
|
||||
</description>
|
||||
</wizard>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.exportWizards">
|
||||
<category
|
||||
@ -50,6 +67,9 @@
|
||||
icon="icons/brick_go.png"
|
||||
id="ghidradev.ghidraprojectcreator.wizards.ExportGhidraModuleWizard"
|
||||
name="Ghidra Module Extension">
|
||||
<description>
|
||||
Exports a Ghidra module project to a zipped Ghidra extension.
|
||||
</description>
|
||||
</wizard>
|
||||
</extension>
|
||||
<extension
|
||||
@ -146,6 +166,19 @@
|
||||
</parameter>
|
||||
</command>
|
||||
</menu>
|
||||
<menu
|
||||
label="Import">
|
||||
<command
|
||||
commandId="org.eclipse.ui.file.import"
|
||||
icon="icons/brick_add.png"
|
||||
label="Ghidra Module Source"
|
||||
style="push">
|
||||
<parameter
|
||||
name="importWizardId"
|
||||
value="ghidradev.ghidraprojectcreator.wizards.ImportGhidraModuleWizard">
|
||||
</parameter>
|
||||
</command>
|
||||
</menu>
|
||||
<menu
|
||||
label="Export">
|
||||
<command
|
||||
|
@ -73,6 +73,15 @@ public class GhidraLaunchDelegate extends JavaLaunchDelegate {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure there isn't a build/ directory present...it messes up the classpath.
|
||||
// The build directory could exist if the user built an extension from the command line
|
||||
// rather than from the Eclipse wizard
|
||||
if (javaProject.getProject().getFolder("build").exists()) {
|
||||
EclipseMessageUtils.showErrorDialog("Failed to launch project \"" + projectName +
|
||||
"\".\nDelete top-level 'build' directory and try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set program arguments
|
||||
String customProgramArgs =
|
||||
configuration.getAttribute(GhidraLaunchUtils.ATTR_PROGAM_ARGUMENTS, "").trim();
|
||||
|
@ -44,6 +44,12 @@ public class GhidraProjectCreatorPreferences {
|
||||
*/
|
||||
static final String GHIDRA_LAST_PROJECT_ROOT_PATH = "ghidradev.ghidraLastProjectRootPath";
|
||||
|
||||
/**
|
||||
* Path to the last used Ghidra module source directory.
|
||||
*/
|
||||
static final String GHIDRA_LAST_MODULE_SOURCE_DIR_PATH =
|
||||
"ghidradev.ghidraLastModuleSourceDirPath";
|
||||
|
||||
/**
|
||||
* The last used Gradle distribution.
|
||||
*/
|
||||
@ -123,6 +129,28 @@ public class GhidraProjectCreatorPreferences {
|
||||
prefs.setValue(GHIDRA_LAST_PROJECT_ROOT_PATH, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last used Ghidra module source directory path that's defined in the preferences.
|
||||
*
|
||||
* @return The last used Ghidra module source directory path that's defined in the preferences.
|
||||
* Could be the empty string.
|
||||
*/
|
||||
public static String getGhidraLastModuleSourceDirPath() {
|
||||
IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
|
||||
return prefs.getString(GHIDRA_LAST_MODULE_SOURCE_DIR_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last used Ghidra module source directory path that's defined in the preferences.
|
||||
*
|
||||
* @param path The last used Ghidra module source directory path that's defined in the
|
||||
* preferences.
|
||||
*/
|
||||
public static void setGhidraLastModuleSourceDirPath(String path) {
|
||||
IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
|
||||
prefs.setValue(GHIDRA_LAST_MODULE_SOURCE_DIR_PATH, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last used Ghidra Gradle distribution that's defined in the preferences.
|
||||
*
|
||||
|
@ -32,6 +32,7 @@ import ghidra.GhidraLauncher;
|
||||
/**
|
||||
* Utility methods for working with Ghidra launchers in Eclipse.
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class GhidraLaunchUtils {
|
||||
|
||||
/**
|
||||
|
@ -94,6 +94,7 @@ public class GhidraModuleUtils {
|
||||
sourceFolders.add(project.getFolder("src/main/java"));
|
||||
sourceFolders.add(project.getFolder("src/main/help"));
|
||||
sourceFolders.add(project.getFolder("src/main/resources"));
|
||||
sourceFolders.add(project.getFolder("src/test/java"));
|
||||
sourceFolders.add(project.getFolder("ghidra_scripts"));
|
||||
for (IFolder sourceFolder : sourceFolders) {
|
||||
GhidraProjectUtils.createFolder(sourceFolder, monitor);
|
||||
@ -203,6 +204,76 @@ public class GhidraModuleUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a Ghidra module source directory to a new Ghidra module project with the given name.
|
||||
*
|
||||
* @param projectName The name of the project to create.
|
||||
* @param moduleSourceDir The module source directory to import.
|
||||
* @param createRunConfig Whether or not to create a new run configuration for the project.
|
||||
* @param runConfigMemory The run configuration's desired memory. Could be null.
|
||||
* @param ghidraLayout The Ghidra layout to link the project to.
|
||||
* @param jythonInterpreterName The name of the Jython interpreter to use for Python support.
|
||||
* Could be null if Python support is not wanted.
|
||||
* @param monitor The progress monitor to use during project creation.
|
||||
* @return The imported project.
|
||||
* @throws IOException If there was a file-related problem with creating the project.
|
||||
* @throws ParseException If there was a parse-related problem with creating the project.
|
||||
* @throws CoreException If there was an Eclipse-related problem with creating the project.
|
||||
*/
|
||||
public static IJavaProject importGhidraModuleSource(String projectName, File moduleSourceDir,
|
||||
boolean createRunConfig, String runConfigMemory, GhidraApplicationLayout ghidraLayout,
|
||||
String jythonInterpreterName, IProgressMonitor monitor)
|
||||
throws IOException, ParseException, CoreException {
|
||||
|
||||
// Create empty Ghidra project
|
||||
IJavaProject javaProject =
|
||||
GhidraProjectUtils.createEmptyGhidraProject(projectName, moduleSourceDir,
|
||||
createRunConfig, runConfigMemory, ghidraLayout, jythonInterpreterName, monitor);
|
||||
IProject project = javaProject.getProject();
|
||||
|
||||
// Find source directory paths
|
||||
List<IPath> sourcePaths = new ArrayList<>();
|
||||
IFolder srcFolder = project.getFolder("src");
|
||||
List<IFolder> srcSubFolders = getSubFolders(srcFolder);
|
||||
if (!srcSubFolders.isEmpty()) {
|
||||
for (IFolder srcSubFolder : srcSubFolders) {
|
||||
List<IFolder> subSubFolders = getSubFolders(srcSubFolder);
|
||||
if (!subSubFolders.isEmpty()) {
|
||||
sourcePaths.addAll(subSubFolders.stream().map(e -> e.getFullPath()).toList());
|
||||
}
|
||||
else {
|
||||
sourcePaths.add(srcSubFolder.getFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
sourcePaths.add(srcFolder.getFullPath());
|
||||
}
|
||||
|
||||
// Find jar file paths
|
||||
List<IPath> jarPaths = new ArrayList<>();
|
||||
IFolder libFolder = project.getFolder("lib");
|
||||
if (libFolder.exists()) {
|
||||
for (IResource resource : libFolder.members()) {
|
||||
if (resource.getType() == IResource.FILE &&
|
||||
resource.getFileExtension().equals("jar")) {
|
||||
jarPaths.add(resource.getFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put the source and jar paths in the project's classpath
|
||||
List<IClasspathEntry> cp = new ArrayList<>();
|
||||
cp.addAll(sourcePaths.stream().map(e -> JavaCore.newSourceEntry(e)).toList());
|
||||
cp.addAll(jarPaths.stream().map(e -> JavaCore.newLibraryEntry(e, null, null)).toList());
|
||||
GhidraProjectUtils.addToClasspath(javaProject, cp, monitor);
|
||||
|
||||
// Update language ant properties file
|
||||
GhidraModuleUtils.writeAntProperties(project, ghidraLayout);
|
||||
|
||||
return javaProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes project-specific ant properties, which get imported by the module project's language
|
||||
* build.xml file to allow building against a Ghidra that lives in an external location. If the
|
||||
@ -278,4 +349,24 @@ public class GhidraModuleUtils {
|
||||
Change change = refactoring.createChange(monitor);
|
||||
change.perform(monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link List} of sub-folders
|
||||
*
|
||||
* @param folder The folder to get the sub-folders of
|
||||
* @return A {@link List} of
|
||||
* @throws CoreException If there was an Eclipse-related problem getting the sub-folders
|
||||
*/
|
||||
private static List<IFolder> getSubFolders(IFolder folder) throws CoreException {
|
||||
List<IFolder> subFolders = new ArrayList<>();
|
||||
if (folder.exists()) {
|
||||
for (IResource resource : folder.members()) {
|
||||
if (resource.getType() == IResource.FOLDER) {
|
||||
subFolders.add(folder.getFolder(resource.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return subFolders;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package ghidradev.ghidraprojectcreator.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
|
||||
@ -43,6 +44,7 @@ import utility.module.ModuleUtilities;
|
||||
/**
|
||||
* Utility methods for working with Eclipse Ghidra projects.
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class GhidraProjectUtils {
|
||||
|
||||
/**
|
||||
@ -290,6 +292,9 @@ public class GhidraProjectUtils {
|
||||
IJavaProject javaProject = JavaCore.create(project);
|
||||
project.open(monitor);
|
||||
|
||||
// Set the project's default encoding
|
||||
project.setDefaultCharset(StandardCharsets.UTF_8.displayName(), monitor);
|
||||
|
||||
// Clear the project's classpath
|
||||
javaProject.setRawClasspath(new IClasspathEntry[0], monitor);
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class CreateGhidraModuleProjectWizard extends Wizard implements INewWizar
|
||||
@Override
|
||||
public void init(IWorkbench wb, IStructuredSelection selection) {
|
||||
workbench = wb;
|
||||
projectPage = new CreateGhidraProjectWizardPage();
|
||||
projectPage = new CreateGhidraProjectWizardPage(true);
|
||||
projectConfigPage = new ConfigureGhidraModuleProjectWizardPage();
|
||||
ghidraInstallationPage = new ChooseGhidraInstallationWizardPage();
|
||||
pythonPage = new EnablePythonWizardPage(ghidraInstallationPage);
|
||||
|
@ -54,7 +54,7 @@ public class CreateGhidraScriptProjectWizard extends Wizard implements INewWizar
|
||||
|
||||
@Override
|
||||
public void init(IWorkbench wb, IStructuredSelection selection) {
|
||||
projectPage = new CreateGhidraProjectWizardPage("GhidraScripts");
|
||||
projectPage = new CreateGhidraProjectWizardPage("GhidraScripts", true);
|
||||
projectConfigPage = new ConfigureGhidraScriptProjectWizardPage();
|
||||
ghidraInstallationPage = new ChooseGhidraInstallationWizardPage();
|
||||
pythonPage = new EnablePythonWizardPage(ghidraInstallationPage);
|
||||
|
@ -41,6 +41,7 @@ import org.eclipse.ui.IWorkbench;
|
||||
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.launch.JavaConfig;
|
||||
import ghidradev.EclipseMessageUtils;
|
||||
import ghidradev.ghidraprojectcreator.utils.GhidraProjectUtils;
|
||||
import ghidradev.ghidraprojectcreator.wizards.pages.ChooseGhidraModuleProjectWizardPage;
|
||||
import ghidradev.ghidraprojectcreator.wizards.pages.ConfigureGradleWizardPage;
|
||||
@ -77,6 +78,10 @@ public class ExportGhidraModuleWizard extends Wizard implements INewWizard {
|
||||
|
||||
@Override
|
||||
public boolean performFinish() {
|
||||
if (!validate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IJavaProject javaProject = projectPage.getGhidraModuleProject();
|
||||
GradleDistribution gradleDist = gradlePage.getGradleDistribution();
|
||||
try {
|
||||
@ -169,4 +174,26 @@ public class ExportGhidraModuleWizard extends Wizard implements INewWizard {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the wizard pages. If they are invalid, an error popup will be displayed which
|
||||
* will indicate the problem.
|
||||
*
|
||||
* @return True if the data returned from the wizard pages are valid; otherwise, false
|
||||
*/
|
||||
private boolean validate() {
|
||||
String title = "Invalid Ghidra Module Extension";
|
||||
IJavaProject javaProject = projectPage.getGhidraModuleProject();
|
||||
if (!javaProject.getProject().getFile("extension.properties").exists()) {
|
||||
EclipseMessageUtils.showErrorDialog(title,
|
||||
"Cannot export extension because 'extension.properties' file does not exist.");
|
||||
return false;
|
||||
}
|
||||
if (!javaProject.getProject().getFile("Module.manifest").exists()) {
|
||||
EclipseMessageUtils.showErrorDialog(title,
|
||||
"Cannot export extension because 'Module.manifest' file does not exist.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,150 @@
|
||||
/* ###
|
||||
* 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.wizards;
|
||||
|
||||
import static ghidradev.EclipseMessageUtils.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.wizard.Wizard;
|
||||
import org.eclipse.ui.IImportWizard;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidradev.EclipseMessageUtils;
|
||||
import ghidradev.ghidraprojectcreator.utils.GhidraModuleUtils;
|
||||
import ghidradev.ghidraprojectcreator.wizards.pages.*;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
/**
|
||||
* Wizard for importing Ghidra module source to a new Ghidra module project.
|
||||
*/
|
||||
public class ImportGhidraModuleSourceWizard extends Wizard implements IImportWizard {
|
||||
|
||||
private ChooseGhidraModuleSourceWizardPage sourcePage;
|
||||
private CreateGhidraProjectWizardPage projectPage;
|
||||
private ChooseGhidraInstallationWizardPage ghidraInstallationPage;
|
||||
private EnablePythonWizardPage pythonPage;
|
||||
|
||||
public ImportGhidraModuleSourceWizard() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IWorkbench wb, IStructuredSelection selection) {
|
||||
sourcePage = new ChooseGhidraModuleSourceWizardPage();
|
||||
projectPage = new CreateGhidraProjectWizardPage(false);
|
||||
ghidraInstallationPage = new ChooseGhidraInstallationWizardPage();
|
||||
pythonPage = new EnablePythonWizardPage(ghidraInstallationPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPages() {
|
||||
addPage(sourcePage);
|
||||
addPage(projectPage);
|
||||
addPage(ghidraInstallationPage);
|
||||
addPage(pythonPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performFinish() {
|
||||
if (!validate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File moduleSourceDir = sourcePage.getSourceDir();
|
||||
File ghidraInstallDir = ghidraInstallationPage.getGhidraInstallDir();
|
||||
String projectName = projectPage.getProjectName();
|
||||
boolean createRunConfig = projectPage.shouldCreateRunConfig();
|
||||
String runConfigMemory = projectPage.getRunConfigMemory();
|
||||
String jythonInterpreterName = pythonPage.getJythonInterpreterName();
|
||||
try {
|
||||
getContainer().run(true, false,
|
||||
monitor -> importModuleSource(ghidraInstallDir, projectName, moduleSourceDir,
|
||||
createRunConfig, runConfigMemory, jythonInterpreterName, monitor));
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return false;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
error(showWizardErrorDialog(getShell(), e), e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a Ghidra module source directory to a new Ghidra module project.
|
||||
*
|
||||
* @param ghidraInstallDir The Ghidra installation directory to use.
|
||||
* @param projectName The name of the project to create.
|
||||
* @param moduleSourceDir The module source directory to import.
|
||||
* @param createRunConfig Whether or not to create a new run configuration for the project.
|
||||
* @param runConfigMemory The run configuration's desired memory. Could be null.
|
||||
* @param jythonInterpreterName The name of the Jython interpreter to use for Python support.
|
||||
* Could be null if Python support is not wanted.
|
||||
* @param monitor The monitor to use during project creation.
|
||||
* @throws InvocationTargetException if an error occurred during project creation.
|
||||
*/
|
||||
private void importModuleSource(File ghidraInstallDir, String projectName, File moduleSourceDir,
|
||||
boolean createRunConfig, String runConfigMemory, String jythonInterpreterName,
|
||||
IProgressMonitor monitor) throws InvocationTargetException {
|
||||
try {
|
||||
info("Importing " + projectName + " at " + moduleSourceDir);
|
||||
monitor.beginTask("Importing " + projectName, 2);
|
||||
|
||||
GhidraApplicationLayout ghidraLayout = new GhidraApplicationLayout(ghidraInstallDir);
|
||||
monitor.worked(1);
|
||||
|
||||
GhidraModuleUtils.importGhidraModuleSource(projectName, moduleSourceDir,
|
||||
createRunConfig, runConfigMemory, ghidraLayout, jythonInterpreterName, monitor);
|
||||
monitor.worked(1);
|
||||
|
||||
info("Finished importing " + projectName);
|
||||
}
|
||||
catch (IOException | ParseException | CoreException e) {
|
||||
throw new InvocationTargetException(e);
|
||||
}
|
||||
finally {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the wizard pages. If they are invalid, an error popup will be displayed which
|
||||
* will indicate the problem.
|
||||
*
|
||||
* @return True if the data returned from the wizard pages are valid; otherwise, false
|
||||
*/
|
||||
private boolean validate() {
|
||||
if (FileUtilities.isPathContainedWithin(ghidraInstallationPage.getGhidraInstallDir(),
|
||||
sourcePage.getSourceDir())) {
|
||||
EclipseMessageUtils.showErrorDialog("Invalid Module Source Directory",
|
||||
"Module source directory cannot reside inside of the selected Ghidra installation directory.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/* ###
|
||||
* 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.wizards.pages;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.jface.wizard.WizardPage;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
|
||||
import ghidradev.ghidraprojectcreator.preferences.GhidraProjectCreatorPreferences;
|
||||
|
||||
/**
|
||||
* A wizard page that lets the user choose a Ghidra module source directory.
|
||||
*/
|
||||
public class ChooseGhidraModuleSourceWizardPage extends WizardPage {
|
||||
|
||||
private Text sourceDirText;
|
||||
private Button sourceDirButton;
|
||||
|
||||
/**
|
||||
* Creates a new Ghidra module source chooser wizard page.
|
||||
*/
|
||||
public ChooseGhidraModuleSourceWizardPage() {
|
||||
super("ChooseGhidraModuleSourceWizardPage");
|
||||
setTitle("Choose Ghidra Module Source");
|
||||
setDescription("Choose a Ghidra module source directory.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createControl(Composite parent) {
|
||||
|
||||
Composite container = new Composite(parent, SWT.NULL);
|
||||
container.setLayout(new GridLayout(3, false));
|
||||
|
||||
// Source directory
|
||||
Label sourceDirLabel = new Label(container, SWT.NULL);
|
||||
String sourceDirToolTip = "The Ghidra module source directory.";
|
||||
sourceDirLabel.setText("Source directory:");
|
||||
sourceDirLabel.setToolTipText(sourceDirToolTip);
|
||||
sourceDirText = new Text(container, SWT.BORDER | SWT.SINGLE);
|
||||
sourceDirText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
sourceDirText.setText(GhidraProjectCreatorPreferences.getGhidraLastModuleSourceDirPath());
|
||||
sourceDirText.addModifyListener(evt -> validate());
|
||||
sourceDirText.setToolTipText(sourceDirToolTip);
|
||||
sourceDirButton = new Button(container, SWT.BUTTON1);
|
||||
sourceDirButton.setText("...");
|
||||
sourceDirButton.setToolTipText("Browse to select source directory");
|
||||
sourceDirButton.addListener(SWT.Selection, evt -> {
|
||||
DirectoryDialog dialog = new DirectoryDialog(container.getShell());
|
||||
String path = dialog.open();
|
||||
if (path != null) {
|
||||
sourceDirText.setText(path);
|
||||
}
|
||||
});
|
||||
|
||||
validate();
|
||||
setControl(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the module source directory.
|
||||
*
|
||||
* @return The module source directory. Could be null if unspecified, however, the page will not
|
||||
* be valid until the module source directory is valid, so it should never be null when called
|
||||
* by other classes.
|
||||
*/
|
||||
public File getSourceDir() {
|
||||
if (sourceDirText.getText().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return new File(sourceDirText.getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the fields on the page and updates the page's status.
|
||||
* Should be called every time a field on the page changes.
|
||||
*/
|
||||
private void validate() {
|
||||
String message = null;
|
||||
File sourceDir = new File(sourceDirText.getText());
|
||||
|
||||
if (!sourceDir.isAbsolute()) {
|
||||
message = "Source directory must be an absolute path";
|
||||
}
|
||||
else if (!sourceDir.isDirectory()) {
|
||||
message = "Source directory does not exist";
|
||||
}
|
||||
else if (!new File(sourceDir, "Module.manifest").exists()) {
|
||||
message = "Source directory does not contain a Module.manifest file";
|
||||
}
|
||||
else if (!new File(sourceDir, "build.gradle").exists()) {
|
||||
message = "Source directory does not contain a build.gradle file";
|
||||
}
|
||||
else if (new File(sourceDir, ".project").exists()) {
|
||||
message = "Source directory already contains a .project file";
|
||||
}
|
||||
else if (new File(sourceDir, ".classpath").exists()) {
|
||||
message = "Source directory already contains a .classpath file";
|
||||
}
|
||||
|
||||
setErrorMessage(message);
|
||||
setPageComplete(message == null);
|
||||
if (message == null) {
|
||||
GhidraProjectCreatorPreferences
|
||||
.setGhidraLastModuleSourceDirPath(sourceDirText.getText());
|
||||
}
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ import ghidradev.ghidraprojectcreator.utils.GhidraProjectUtils;
|
||||
public class CreateGhidraProjectWizardPage extends WizardPage {
|
||||
|
||||
private String suggestedProjectName;
|
||||
private boolean showProjectDir;
|
||||
|
||||
private Text projectNameText;
|
||||
private Text projectRootDirText;
|
||||
@ -50,19 +51,25 @@ public class CreateGhidraProjectWizardPage extends WizardPage {
|
||||
* Creates a Ghidra new project wizard page with the given suggested project name.
|
||||
*
|
||||
* @param suggestedProjectName The suggested project name.
|
||||
* @param showProjectDir True to show a component for selecting the root project directory;
|
||||
* otherwise, false
|
||||
*/
|
||||
public CreateGhidraProjectWizardPage(String suggestedProjectName) {
|
||||
public CreateGhidraProjectWizardPage(String suggestedProjectName, boolean showProjectDir) {
|
||||
super("CreateGhidraProjectWizardPage");
|
||||
setTitle("Create Ghidra Project");
|
||||
setDescription("Create a new Ghidra project.");
|
||||
this.suggestedProjectName = suggestedProjectName;
|
||||
this.showProjectDir = showProjectDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Ghidra new project wizard page.
|
||||
*
|
||||
* @param showProjectDir True to show a component for selecting the root project directory;
|
||||
* otherwise, false
|
||||
*/
|
||||
public CreateGhidraProjectWizardPage() {
|
||||
this("");
|
||||
public CreateGhidraProjectWizardPage(boolean showProjectDir) {
|
||||
this("", showProjectDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,25 +88,28 @@ public class CreateGhidraProjectWizardPage extends WizardPage {
|
||||
new Label(container, SWT.NONE).setText(""); // empty grid cell
|
||||
|
||||
// Project directory
|
||||
Label projectDirLabel = new Label(container, SWT.NULL);
|
||||
String projectDirToolTip = "The directory where this project will be created.";
|
||||
projectDirLabel.setText("Project root directory:");
|
||||
projectDirLabel.setToolTipText(projectDirToolTip);
|
||||
projectRootDirText = new Text(container, SWT.BORDER | SWT.SINGLE);
|
||||
projectRootDirText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
projectRootDirText.setText(GhidraProjectCreatorPreferences.getGhidraLastProjectRootPath());
|
||||
projectRootDirText.addModifyListener(evt -> validate());
|
||||
projectRootDirText.setToolTipText(projectDirToolTip);
|
||||
projectDirButton = new Button(container, SWT.BUTTON1);
|
||||
projectDirButton.setText("...");
|
||||
projectDirButton.setToolTipText("Browse to select project root directory");
|
||||
projectDirButton.addListener(SWT.Selection, evt -> {
|
||||
DirectoryDialog dialog = new DirectoryDialog(container.getShell());
|
||||
String path = dialog.open();
|
||||
if (path != null) {
|
||||
projectRootDirText.setText(path);
|
||||
}
|
||||
});
|
||||
if (showProjectDir) {
|
||||
Label projectDirLabel = new Label(container, SWT.NULL);
|
||||
String projectDirToolTip = "The directory where this project will be created.";
|
||||
projectDirLabel.setText("Project root directory:");
|
||||
projectDirLabel.setToolTipText(projectDirToolTip);
|
||||
projectRootDirText = new Text(container, SWT.BORDER | SWT.SINGLE);
|
||||
projectRootDirText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
projectRootDirText
|
||||
.setText(GhidraProjectCreatorPreferences.getGhidraLastProjectRootPath());
|
||||
projectRootDirText.addModifyListener(evt -> validate());
|
||||
projectRootDirText.setToolTipText(projectDirToolTip);
|
||||
projectDirButton = new Button(container, SWT.BUTTON1);
|
||||
projectDirButton.setText("...");
|
||||
projectDirButton.setToolTipText("Browse to select project root directory");
|
||||
projectDirButton.addListener(SWT.Selection, evt -> {
|
||||
DirectoryDialog dialog = new DirectoryDialog(container.getShell());
|
||||
String path = dialog.open();
|
||||
if (path != null) {
|
||||
projectRootDirText.setText(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Create run configuration checkbox
|
||||
createRunConfigCheckboxButton = new Button(container, SWT.CHECK);
|
||||
@ -153,14 +163,13 @@ public class CreateGhidraProjectWizardPage extends WizardPage {
|
||||
* Gets the project directory. This is the directory where the .project file should live.
|
||||
*
|
||||
* @return The project directory. This is the directory where the .project file should live.
|
||||
* Could be null if unspecified, however, the page will not be valid until the project
|
||||
* directory is valid, so it should never be null when called by other classes.
|
||||
* Could be null if unspecified.
|
||||
*/
|
||||
public File getProjectDir() {
|
||||
if (projectNameText.getText().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (projectRootDirText.getText().isEmpty()) {
|
||||
if (projectRootDirText == null || projectRootDirText.getText().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return new File(projectRootDirText.getText(), getProjectName());
|
||||
@ -227,10 +236,10 @@ public class CreateGhidraProjectWizardPage extends WizardPage {
|
||||
else if (BAD.chars().anyMatch(ch -> projectName.indexOf(ch) != -1)) {
|
||||
message = "Project name cannot contain invalid characters:\n " + BAD;
|
||||
}
|
||||
else if (projectDir == null) {
|
||||
else if (showProjectDir && projectDir == null) {
|
||||
message = "Project root directory must be specified";
|
||||
}
|
||||
else if (projectDir.exists()) {
|
||||
else if (showProjectDir && projectDir.exists()) {
|
||||
message = "Project already exists at: " + projectDir.getAbsolutePath();
|
||||
}
|
||||
else if (ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).exists()) {
|
||||
@ -250,8 +259,10 @@ public class CreateGhidraProjectWizardPage extends WizardPage {
|
||||
setErrorMessage(message);
|
||||
setPageComplete(message == null);
|
||||
if (message == null) {
|
||||
GhidraProjectCreatorPreferences.setGhidraLastProjectRootPath(
|
||||
projectRootDirText.getText());
|
||||
if (projectRootDirText != null) {
|
||||
GhidraProjectCreatorPreferences
|
||||
.setGhidraLastProjectRootPath(projectRootDirText.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import org.eclipse.ui.ide.IDE;
|
||||
|
||||
import ghidradev.EclipseMessageUtils;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class OpenDeclarations {
|
||||
|
||||
private IProject project;
|
||||
|
@ -37,6 +37,7 @@ rootProject.assembleDistribution {
|
||||
exclude '.project'
|
||||
exclude 'build.gradle'
|
||||
rename "buildTemplate.gradle", "build.gradle"
|
||||
rename "gitignore", ".gitignore"
|
||||
into "Extensions/Ghidra/Skeleton"
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ data/languages/skel.slaspec||GHIDRA||||END|
|
||||
data/sleighArgs.txt||GHIDRA||||END|
|
||||
extension.properties||GHIDRA||||END|
|
||||
ghidra_scripts/README.txt||GHIDRA||||END|
|
||||
gitignore||GHIDRA||||END|
|
||||
lib/README.txt||GHIDRA||||END|
|
||||
os/linux_x86_64/README.txt||GHIDRA||||END|
|
||||
os/mac_x86_64/README.txt||GHIDRA||||END|
|
||||
|
10
GhidraBuild/Skeleton/gitignore
Normal file
10
GhidraBuild/Skeleton/gitignore
Normal file
@ -0,0 +1,10 @@
|
||||
.project
|
||||
.pyproject
|
||||
.classpath
|
||||
.settings/
|
||||
.gradle/
|
||||
bin/
|
||||
build/
|
||||
dist/
|
||||
*.swp
|
||||
.antProperties.xml
|
@ -41,7 +41,7 @@ public class SkeletonAnalyzer extends AbstractAnalyzer {
|
||||
|
||||
// TODO: Return true if analyzer should be enabled by default
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -50,7 +50,7 @@ public class SkeletonAnalyzer extends AbstractAnalyzer {
|
||||
// TODO: Examine 'program' to determine of this analyzer should analyze it. Return true
|
||||
// if it can.
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user