diff --git a/Ghidra/Features/Base/developer_scripts/BuildResultState.java b/Ghidra/Features/Base/developer_scripts/BuildResultState.java index 881f8038bd..2671176d09 100644 --- a/Ghidra/Features/Base/developer_scripts/BuildResultState.java +++ b/Ghidra/Features/Base/developer_scripts/BuildResultState.java @@ -220,9 +220,9 @@ public class BuildResultState extends GhidraScript { // } // Register[] regs = currentProgram.getLanguage().getRegisters(); + List registers = Arrays.asList(regs); try { - Register reg = - askChoice("Results Query", "Select Register:", Arrays.asList(regs), null); + Register reg = askChoice("Results Query", "Select Register:", registers, null); while (reg != null) { boolean first = true; boolean preserved = true; @@ -242,7 +242,7 @@ public class BuildResultState extends GhidraScript { System.out.println(reg.getName() + " value is preserved."); } - reg = askChoice("Results Query", "Select Register:", regs, null); + reg = askChoice("Results Query", "Select Register:", registers, null); } } catch (CancelledException e) { diff --git a/Ghidra/Features/Base/developer_scripts/FixLangId.java b/Ghidra/Features/Base/developer_scripts/FixLangId.java index 91ddccadb5..6fcffe1130 100644 --- a/Ghidra/Features/Base/developer_scripts/FixLangId.java +++ b/Ghidra/Features/Base/developer_scripts/FixLangId.java @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; import javax.swing.SwingUtilities; @@ -83,8 +82,8 @@ public class FixLangId extends GhidraScript { dbh.close(); } - private boolean modifyLanguage(DomainFile df, DBHandle dbh) throws IOException, - ImproperUseException { + private boolean modifyLanguage(DomainFile df, DBHandle dbh) + throws IOException, ImproperUseException { // TODO: Check for address map and overlay entries which could break from // changing the memory model !! @@ -104,9 +103,9 @@ public class FixLangId extends GhidraScript { LanguageDescription desc = null; List descriptions = DefaultLanguageService.getLanguageService().getLanguageDescriptions(true); - String[] choices = new String[descriptions.size()]; - for (int i = 0; i < choices.length; i++) { - choices[i] = descriptions.get(i).getLanguageID().getIdAsString(); + List choices = new ArrayList<>(descriptions.size()); + for (int i = 0; i < choices.size(); i++) { + choices.add(descriptions.get(i).getLanguageID().getIdAsString()); } try { @@ -114,9 +113,8 @@ public class FixLangId extends GhidraScript { if (langId != null) { Msg.warn(this, "Changing language ID from '" + record.getString(0) + "' to '" + langId + "' for program: " + df.getName()); - desc = - DefaultLanguageService.getLanguageService().getLanguageDescription( - new LanguageID(langId)); + desc = DefaultLanguageService.getLanguageService().getLanguageDescription( + new LanguageID(langId)); long txId = dbh.startTransaction(); try { record.setString(0, langId); @@ -140,20 +138,12 @@ public class FixLangId extends GhidraScript { public DomainFile askProgramFile(String title) { final DomainFile[] domainFile = new DomainFile[] { null }; final DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.OPEN); - dtd.addOkActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - dtd.close(); - domainFile[0] = dtd.getDomainFile(); - } + dtd.addOkActionListener(e -> { + dtd.close(); + domainFile[0] = dtd.getDomainFile(); }); try { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - dtd.showComponent(); - } - }); + SwingUtilities.invokeAndWait(() -> dtd.showComponent()); } catch (Exception e) { return null; diff --git a/Ghidra/Features/Base/ghidra_scripts/AskScript.java b/Ghidra/Features/Base/ghidra_scripts/AskScript.java index 29eae401bc..3fe0fddc6a 100644 --- a/Ghidra/Features/Base/ghidra_scripts/AskScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/AskScript.java @@ -89,7 +89,8 @@ public class AskScript extends GhidraScript { println("You typed: " + myStr + " and " + myOtherStr); String choice = askChoice("Choice", "Please choose one", - new String[] { "grumpy", "dopey", "sleepy", "doc", "bashful" }, "bashful"); + Arrays.asList(new String[] { "grumpy", "dopey", "sleepy", "doc", "bashful" }), + "bashful"); println("Choice? " + choice); List choices1 = askChoices("Choices 1", "Please choose one or more numbers.", diff --git a/Ghidra/Features/Base/ghidra_scripts/CreatePdbXmlFilesScript.java b/Ghidra/Features/Base/ghidra_scripts/CreatePdbXmlFilesScript.java index 60ca0065aa..437962966e 100644 --- a/Ghidra/Features/Base/ghidra_scripts/CreatePdbXmlFilesScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/CreatePdbXmlFilesScript.java @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import java.io.*; +import java.util.*; + import ghidra.app.script.GhidraScript; import ghidra.framework.*; -import java.io.*; -import java.util.ArrayList; -import java.util.List; - /** * * Asks user for a single .pdb file or a directory that contains .pdb files (search for @@ -46,10 +45,10 @@ public class CreatePdbXmlFilesScript extends GhidraScript { // Get appropriate pdb.exe file String pdbExeLocation = Application.getOSFile("pdb.exe").getAbsolutePath(); - String[] choices = new String[] { "single file", "directory of files" }; - String fileOrDir = - askChoice("PDB file or directory", "Would you like to operate on a single " - + ".pdb file or a directory of .pdb files?", choices, choices[1]); + List choices = Arrays.asList("single file", "directory of files"); + String fileOrDir = askChoice("PDB file or directory", + "Would you like to operate on a single " + ".pdb file or a directory of .pdb files?", + choices, choices.get(1)); File pdbParentDir; String pdbName; @@ -57,7 +56,7 @@ public class CreatePdbXmlFilesScript extends GhidraScript { int filesCreated = 0; try { - if (fileOrDir.equals(choices[0])) { + if (fileOrDir.equals(choices.get(0))) { File pdbFile = askFile("Choose a PDB file", "OK"); if (!pdbFile.exists()) { @@ -82,12 +81,11 @@ public class CreatePdbXmlFilesScript extends GhidraScript { } else { // Do recursive processing - File pdbDir = - askDirectory( - "Choose PDB root folder (performs recursive search for .pdb files)", "OK"); + File pdbDir = askDirectory( + "Choose PDB root folder (performs recursive search for .pdb files)", "OK"); // Get list of files to process - List pdbFiles = new ArrayList(); + List pdbFiles = new ArrayList<>(); getPDBFiles(pdbDir, pdbFiles); int createdFilesCounter = 0; @@ -157,8 +155,8 @@ public class CreatePdbXmlFilesScript extends GhidraScript { createdFile.delete(); } - throw new IOException("At file '" + pdbName + - "':\nAbnormal termination of 'pdb.exe' process."); + throw new IOException( + "At file '" + pdbName + "':\nAbnormal termination of 'pdb.exe' process."); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java index 328e9c8479..0bf7597429 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java @@ -17,11 +17,9 @@ package ghidra.app.script; import java.awt.Color; import java.io.*; -import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.rmi.ConnectException; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import javax.swing.SwingUtilities; @@ -262,15 +260,12 @@ public abstract class GhidraScript extends FlatProgramAPI { } private void doCleanup(boolean success) { - - // TODO transient cleanup - cleanup(success); } /** - * Will ye, nill ye? - * @param success + * A callback for scripts to perform any needed cleanup after the script is finished + * @param success true if the script was successful */ public void cleanup(boolean success) { // for users to override @@ -296,7 +291,7 @@ public abstract class GhidraScript extends FlatProgramAPI { * * @param dirLocation String representation of the path to the .properties file * @param basename base name of the file - * @throws IOException + * @throws IOException if there is an exception loading the new properties file */ public void setPropertiesFileLocation(String dirLocation, String basename) throws IOException { File testIfDir = new File(dirLocation); @@ -407,23 +402,6 @@ public abstract class GhidraScript extends FlatProgramAPI { return false; } - /** - * Starts auto-analysis on the specified program and performs complete analysis - * of the entire program. This is usually only necessary if full analysis was never - * performed. This method blocks until analysis completes. - * - * @param program the program to analyze - * @deprecated the method {@link #analyzeAll} or {@link #analyzeChanges} should be invoked. - * These separate methods were created to clarify their true behavior since many times it is - * only necessary to analyze changes and not the entire program which can take much - * longer and affect more of the program than is necessary. - */ - @Deprecated - @Override - public void analyze(Program program) { - analyzeAll(program); - } - @Override public void analyzeAll(Program program) { if (program == null) { @@ -508,7 +486,7 @@ public abstract class GhidraScript extends FlatProgramAPI { /** * Set associated source file - * @param sourceFile + * @param sourceFile the source file */ public final void setSourceFile(ResourceFile sourceFile) { this.sourceFile = sourceFile; @@ -617,19 +595,6 @@ public abstract class GhidraScript extends FlatProgramAPI { return null; } - /** - * This method is no longer supported. - * Calling it will result in an UnsupportedOperationException being thrown. - * @param name the name of the script - * - * @deprecated you can no longer change a script's name - * @throws UnsupportedOperationException - */ - @Deprecated - public void setName(String name) { - throw new UnsupportedOperationException("You cannot change a script's name."); - } - /** * Returns the username of the user running the script. * @return the username of the user running the script @@ -1099,22 +1064,6 @@ public abstract class GhidraScript extends FlatProgramAPI { } } - /** - * Returns a list of valid choices, given an analysis option name (if they exist for this - * option). If the analysis option is unconstrained (does not have to be one of a list - * of specific options), returns an empty array. - * - * @param program the program to get analysis option choices from - * @param analysisOption the analysis option to get choices for - * @return an String array of the only valid choices for this analysis option (array is empty if - * choices are unconstrained) - * @deprecated - */ - @Deprecated - public String[] getAnalysisOptionChoices(Program program, String analysisOption) { - return new String[0]; - } - /** * Returns the description of an analysis option name, as provided by the analyzer. This * method returns an empty string if no description is available. @@ -2086,7 +2035,7 @@ public abstract class GhidraScript extends FlatProgramAPI { chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY); ref.set(chooser.getSelectedFile()); }; - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (chooser.wasCancelled()) { throw new CancelledException(); @@ -2169,7 +2118,7 @@ public abstract class GhidraScript extends FlatProgramAPI { chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY); ref.set(chooser.getSelectedFile()); }; - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (chooser.wasCancelled()) { throw new CancelledException(); @@ -2276,7 +2225,7 @@ public abstract class GhidraScript extends FlatProgramAPI { dialog.setSelectedLanguage(lastValue); ref.set(dialog.getSelectedLanguage()); }; - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (dialog.wasCancelled()) { throw new CancelledException(); @@ -2358,7 +2307,7 @@ public abstract class GhidraScript extends FlatProgramAPI { }); Runnable r = () -> dtd.showComponent(); - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (dtd.wasCancelled()) { throw new CancelledException(); @@ -2726,7 +2675,7 @@ public abstract class GhidraScript extends FlatProgramAPI { }); Runnable r = () -> dtd.showComponent(); - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (dtd.wasCancelled()) { throw new CancelledException(); @@ -2818,7 +2767,7 @@ public abstract class GhidraScript extends FlatProgramAPI { }); Runnable r = () -> dtd.showComponent(); - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (dtd.wasCancelled()) { throw new CancelledException(); @@ -3218,7 +3167,7 @@ public abstract class GhidraScript extends FlatProgramAPI { new MultipleOptionsDialog<>(title, message, choices, true); Runnable r = () -> reference.set(dialog.getUserChoices()); - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (dialog.isCanceled()) { throw new CancelledException(); @@ -3295,7 +3244,7 @@ public abstract class GhidraScript extends FlatProgramAPI { new MultipleOptionsDialog<>(title, message, choices, choiceLabels, true); Runnable r = () -> reference.set(dialog.getUserChoices()); - SystemUtilities.runSwingNow(r); + Swing.runNow(r); if (dialog.isCanceled()) { throw new CancelledException(); @@ -3366,16 +3315,7 @@ public abstract class GhidraScript extends FlatProgramAPI { return existingValue; } - AtomicBoolean yesno = new AtomicBoolean(); - - Runnable r = () -> { - int choice = OptionDialog.showYesNoDialog(null, title, question); - yesno.set(choice == OptionDialog.OPTION_ONE); - }; - - SystemUtilities.runSwingNow(r); - - return yesno.get(); + return OptionDialog.showYesNoDialog(null, title, question) == OptionDialog.OPTION_ONE; } /** @@ -3772,7 +3712,7 @@ public abstract class GhidraScript extends FlatProgramAPI { Color.GREEN, null, "Script Results", null); tableProvider.installRemoveItemsAction(); }; - SystemUtilities.runSwingLater(runnable); + Swing.runLater(runnable); } private void show(final String title, final TableService table, @@ -3790,7 +3730,7 @@ public abstract class GhidraScript extends FlatProgramAPI { "GhidraScript", model, Color.GREEN, null, "Script Results", null); tableProvider.installRemoveItemsAction(); }; - SystemUtilities.runSwingLater(runnable); + Swing.runLater(runnable); } private Map, Object> getScriptMap(String title, String message) { @@ -3813,217 +3753,4 @@ public abstract class GhidraScript extends FlatProgramAPI { } return buffer.toString(); } - -//================================================================================================== -// Deprecated Methods - version 2 - Feb 2017 -//================================================================================================== - - /** - * Fetches the text contained within the given portion of the console. - * - * @param offset the offset into the console representing the desired start of the text >= 0 - * @param length the length of the desired string >= 0 - * @return the text, in a String of length >= 0 - * @deprecated deemed not worth supporting due to lack of value - */ - @Deprecated - public String getConsoleText(int offset, int length) { - - PluginTool tool = state.getTool(); - if (tool == null) { - throw new ImproperUseException( - "The getConsoleText() method can only be run within a headed Ghidra."); - } - - ConsoleService console = tool.getService(ConsoleService.class); - if (console == null) { - // the console service is not a dependency - return ""; - } - - return console.getText(offset, length); - } - - /** - * Returns number of characters of currently in the console. - *

- * If the console is cleared, this number is reset. - * - * @return the text in the console, in a String of length >= 0 - * @deprecated deemed not worth supporting due to lack of value - */ - @Deprecated - public int getConsoleTextLength() { - PluginTool tool = state.getTool(); - if (tool == null) { - return 0; - } - - ConsoleService console = tool.getService(ConsoleService.class); - if (console == null) { - return 0; - } - - return console.getTextLength(); - } - -//================================================================================================== -// Deprecated Methods - version 3 - Nov 30 - Ghidra 7.5 -//================================================================================================== - - /** - * Returns an array of Objects representing one or more choices from the given list. The actual - * behavior of the method depends on your environment, which can be GUI or headless. - *

- * Regardless of environment -- if script arguments have been set, this method will use the - * next argument in the array and advance the array index so the next call to an ask method - * will get the next argument. If there are no script arguments and a .properties file - * sharing the same base name as the Ghidra Script exists (i.e., Script1.properties for - * Script1.java), then this method will then look there for the String value to return. - * The method will look in the .properties file by searching for a property name that is a - * space-separated concatenation of the input String parameters (title + " " + message). - * If that property name exists and its value represents valid choices, then the - * .properties value will be used in the following way: - *

    - *
  1. In the GUI environment, this method displays a pop-up dialog that presents the user - * with checkbox choices (to allow a more flexible option where the user can pick - * some, all, or none).
  2. - *
  3. In the headless environment, if a .properties file sharing the same base name as the - * Ghidra Script exists (i.e., Script1.properties for Script1.java), then this method - * looks there for the choices to return. The method will look in the .properties file - * by searching for a property name equal to a space-separated concatenation of the - * String parameters (title + " " + message). If that property name exists and - * represents a list (one or more) of valid choice(s) in the form - * "choice1;choice2;choice3;..." (<-- note the quotes surrounding the choices), then - * an Object array of those choices is returned. Otherwise, an Exception is thrown if - * there is an invalid or missing .properties value.
  4. - *
- * - * @param title the title of the dialog (in GUI mode) or the first part of the variable name - * (in headless mode or when using .properties file) - * @param message the message to display with the choices (in GUI mode) or the second - * part of the variable name (in headless mode or when using .properties file) - * @param choices set of choices (toString() value of each object will be displayed in the dialog) - * @return the user-selected value(s); null if no selection was made - * - * @throws CancelledException if the user hits the 'cancel' button - * @throws IllegalArgumentException if in headless mode, there was a missing or invalid set of - * choices specified in the .properties file - * @deprecated use {@link #askChoices(String, String, List)} instead. - * Deprecated in 7.5 - */ - @Deprecated - @SuppressWarnings("unchecked") - public T[] askChoices(String title, String message, T[] choices) throws CancelledException { - - List choicesList = Arrays.asList(choices); - - List results = askChoices(title, message, choicesList); - T[] array = (T[]) Array.newInstance(choices.getClass().getComponentType(), results.size()); - return results.toArray(array); - } - - /** - * Returns an object that represents one of the choices in the given list. The actual behavior - * of the method depends on your environment, which can be GUI or headless. - *

- * Regardless of environment -- if script arguments have been set, this method will use the - * next argument in the array and advance the array index so the next call to an ask method - * will get the next argument. If there are no script arguments and a .properties file - * sharing the same base name as the Ghidra Script exists (i.e., Script1.properties for - * Script1.java), then this method will then look there for the String value to return. - * The method will look in the .properties file by searching for a property name that is a - * space-separated concatenation of the input String parameters (title + " " + message). - * If that property name exists and its value represents a valid choice, then the - * .properties value will be used in the following way: - *

    - *
  1. In the GUI environment, this method displays a popup dialog that prompts the user - * to choose from the given list of objects. The pre-chosen choice will be the last - * user-chosen value (if the dialog has been run before). If that does not exist, the - * pre-chosen value is the .properties value. If that does not exist or is invalid, - * then the 'defaultValue' parameter is used (as long as it is not null).
  2. - *
  3. In the headless environment, this method returns an object representing the - * .properties value (if it exists and is a valid choice), or throws an Exception if - * there is an invalid or missing .properties value.
  4. - *
- *

- * @param title the title of the dialog (in GUI mode) or the first part of the variable name - * (in headless mode or when using .properties file) - * @param message the message to display next to the input field (in GUI mode) or the second - * part of the variable name (in headless mode or when using .properties file) - * @param choices set of choices (toString() value of each object will be displayed in the dialog) - * @param defaultValue the default value to display in the input field; may be - * null, but must be a valid choice if non-null. - * @return the user-selected value - * @throws CancelledException if the user hit the 'cancel' button - * @throws IllegalArgumentException if in headless mode, there was a missing or invalid choice - * specified in the .properties file - * @deprecated use {@link #askChoice(String, String, List, Object)} instead. - * Deprecated in 7.5 - */ - @Deprecated - public T askChoice(String title, String message, T[] choices, T defaultValue) - throws CancelledException { - - List choicesList = Arrays.asList(choices); - return askChoice(title, message, choicesList, defaultValue); - } - - /** - * Returns an array of Objects representing one or more choices from the given list. The user - * specifies the choices as Objects, also passing along a corresponding array of String - * representations for each choice (used as the checkbox label). The actual behavior of the - * method depends on your environment, which can be GUI or headless. - *

- * Regardless of environment -- if script arguments have been set, this method will use the - * next argument in the array and advance the array index so the next call to an ask method - * will get the next argument. If there are no script arguments and a .properties file - * sharing the same base name as the Ghidra Script exists (i.e., Script1.properties for - * Script1.java), then this method will then look there for the String value to return. - * The method will look in the .properties file by searching for a property name that is a - * space-separated concatenation of the input String parameters (title + " " + message). - * If that property name exists and its value represents valid choices, then the - * .properties value will be used in the following way: - *

    - *
  1. In the GUI environment, this method displays a pop-up dialog that presents the user - * with checkbox choices (to allow a more flexible option where the user can pick - * some, all, or none).
  2. - *
  3. In the headless environment, if a .properties file sharing the same base name as the - * Ghidra Script exists (i.e., Script1.properties for Script1.java), then this method - * looks there for the choices to return. The method will look in the .properties file - * by searching for a property name equal to a space-separated concatenation of the - * String parameters (title + " " + message). If that property name exists and - * represents a list (one or more) of valid choice(s) in the form - * "choice1;choice2;choice3;..." (<-- note the quotes surrounding the choices), then - * an Object array of those choices is returned. Otherwise, an Exception is thrown if - * there is an invalid or missing .properties value. NOTE: the choice names for - * this method must match those in the stringRepresentationOfChoices array.
  4. - *
- * - * @param title the title of the dialog (in GUI mode) or the first part of the variable name - * (in headless mode or when using .properties file) - * @param message the message to display with the choices (in GUI mode) or the second - * part of the variable name (in headless mode or when using .properties file) - * @param choices set of choices - * @param choiceLabels the String representation for each choice, used for - * checkbox labels - * @return the user-selected value(s); an empty list if no selection was made - * - * @throws CancelledException if the user hits the 'cancel' button - * @throws IllegalArgumentException if in headless mode, there was a missing or invalid set of - * choices specified in the .properties file - * @deprecated use {@link #askChoices(String, String, List, List)} instead. - * Deprecated in 7.5 - */ - @Deprecated - public Object[] askChoices(String title, String message, T[] choices, String[] choiceLabels) - throws CancelledException { - - List choicesList = Arrays.asList(choices); - List labelsList = Arrays.asList(choiceLabels); - - List results = askChoices(title, message, choicesList, labelsList); - return results.toArray(new Object[results.size()]); - } - } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProperties.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProperties.java index bc6b1f0cd7..cbb6ae31f3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProperties.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProperties.java @@ -23,7 +23,7 @@ import generic.jar.ResourceFile; import ghidra.util.Msg; /** - * Handles processing for a .properties files associated with a GhidraScript (.properties file and + * Handles processing for .properties files associated with a GhidraScript (.properties file and * script should share the same basename). * * This should only be called/used by the GhidraScript class. @@ -43,6 +43,7 @@ public class GhidraScriptProperties { * * @param scriptLocation location of the GhidraScript * @param newBaseName name of the GhidraScript (without the extension) + * @throws IOException if there is an exception loading the properties file */ protected void loadGhidraScriptProperties(ResourceFile scriptLocation, String newBaseName) throws IOException { @@ -79,8 +80,9 @@ public class GhidraScriptProperties { /** * Look for a .properties file corresponding to the basename in the given locations. * - * @param possibleLocations possible locations where the .properties file can be found - * @param basename name of the GhidraScript (without the extension) + * @param possibleLocations possible locations where the .properties file can be found + * @param newBaseName name of the GhidraScript (without the extension) + * @throws IOException if there is an exception loading the properties file */ protected void loadGhidraScriptProperties(List possibleLocations, String newBaseName) throws IOException { @@ -98,6 +100,7 @@ public class GhidraScriptProperties { * Load a .properties file. * * @param file the .properties file + * @throws IOException if there is an exception loading the properties file */ protected void loadGhidraScriptProperties(ResourceFile file) throws IOException { diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java index 90ceb708b9..507a99625a 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptAskMethodsTest.java @@ -19,8 +19,7 @@ import static org.junit.Assert.*; import java.io.*; import java.net.URL; -import java.util.Arrays; -import java.util.Map; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; @@ -30,7 +29,7 @@ import org.junit.*; import docking.DialogComponentProvider; import docking.widgets.filechooser.GhidraFileChooser; -import generic.test.AbstractGenericTest; +import generic.test.AbstractGTest; import generic.test.TestUtils; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.script.GhidraScriptMgrPlugin; @@ -43,7 +42,7 @@ import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.TestEnv; -import ghidra.util.task.TaskMonitorAdapter; +import ghidra.util.task.TaskMonitor; import utilities.util.FileUtilities; public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationTest { @@ -123,7 +122,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT assertByteArrayEquals(expectedBytes, myBytes); } - /** + /* * Calling askProgram() would stacktrace if the user 1) didn't select a program in the * tree and then 2) pressed the OK button. */ @@ -141,7 +140,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - DataTreeDialog dtd = waitForDialogComponent(null, DataTreeDialog.class, 2000); + DataTreeDialog dtd = waitForDialogComponent(DataTreeDialog.class); JButton okButton = (JButton) getInstanceField("okButton", dtd); runSwing(() -> okButton.doClick()); @@ -152,7 +151,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT runSwing(() -> dtd.close()); } - /** + /* * For scripts with properties files in a different location (could be the case with subscripts), * tests that the .properties file is found in the default location and that the default value * for the input field is provided by the .properties file in the alternate location. @@ -164,7 +163,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT // Create a temporary .properties file and set the potentialPropertiesFileLocs to look // in that location - String tempDirPath = AbstractGenericTest.getTestDirectoryPath(); + String tempDirPath = AbstractGTest.getTestDirectoryPath(); File tempDir = new File(tempDirPath); File tempPropertiesFile = new File(tempDir, "GhidraScriptTest.properties"); tempPropertiesFile.delete(); @@ -200,8 +199,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - AskDialog askDialog = - waitForDialogComponent(env.getTool().getToolFrame(), AskDialog.class, TIMEOUT_MILLIS); + AskDialog askDialog = waitForDialogComponent(AskDialog.class); assertNotNull(askDialog); pressButtonByText(askDialog, "OK"); waitForSwing(); @@ -216,7 +214,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT // Create a temporary files, then create a temporary .properties file that contains // the path to one of the temporary file. - String tempDirPath = AbstractGenericTest.getTestDirectoryPath(); + String tempDirPath = AbstractGTest.getTestDirectoryPath(); File tempDir = new File(tempDirPath); File tempFile = new File(tempDir, "tempFile.exe"); File anotherTempFile = new File(tempDir, "MyTempFile.txt"); @@ -258,8 +256,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - GhidraFileChooser fileChooser = waitForDialogComponent(env.getTool().getToolFrame(), - GhidraFileChooser.class, TIMEOUT_MILLIS * 2); + GhidraFileChooser fileChooser = waitForDialogComponent(GhidraFileChooser.class); waitForUpdateOnDirectory(fileChooser); @@ -281,8 +278,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - fileChooser = waitForDialogComponent(env.getTool().getToolFrame(), GhidraFileChooser.class, - TIMEOUT_MILLIS * 2); + fileChooser = waitForDialogComponent(GhidraFileChooser.class); fileChooser.setSelectedFile(anotherTempFile); waitForUpdateOnDirectory(fileChooser); @@ -300,8 +296,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - fileChooser = waitForDialogComponent(env.getTool().getToolFrame(), GhidraFileChooser.class, - TIMEOUT_MILLIS * 2); + fileChooser = waitForDialogComponent(GhidraFileChooser.class); fileChooser.setSelectedFile(anotherTempFile); waitForUpdateOnDirectory(fileChooser); @@ -324,7 +319,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT // Create temporary directories, then create a temporary .properties file that contains // the path to one of the temporary directory. - String tempDirPath = AbstractGenericTest.getTestDirectoryPath(); + String tempDirPath = AbstractGTest.getTestDirectoryPath(); File tempDir = new File(tempDirPath); File tempSubDir = new File(tempDir, TEMP_SUB_DIR); File anotherTempSubDir = new File(tempDir, "anotherTempDir"); @@ -368,8 +363,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - GhidraFileChooser fileChooser = waitForDialogComponent(env.getTool().getToolFrame(), - GhidraFileChooser.class, TIMEOUT_MILLIS * 2); + GhidraFileChooser fileChooser = waitForDialogComponent(GhidraFileChooser.class); waitForUpdateOnDirectory(fileChooser); assertNotNull(fileChooser); @@ -390,8 +384,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - fileChooser = waitForDialogComponent(env.getTool().getToolFrame(), GhidraFileChooser.class, - TIMEOUT_MILLIS * 2); + fileChooser = waitForDialogComponent(GhidraFileChooser.class); fileChooser.setSelectedFile(anotherTempSubDir); waitForUpdateOnDirectory(fileChooser); @@ -409,8 +402,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }); - fileChooser = waitForDialogComponent(env.getTool().getToolFrame(), GhidraFileChooser.class, - TIMEOUT_MILLIS * 2); + fileChooser = waitForDialogComponent(GhidraFileChooser.class); waitForUpdateOnDirectory(fileChooser); pressButtonByText(fileChooser, "Choose!"); @@ -444,8 +436,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - SelectLanguageDialog langDialog = waitForDialogComponent(env.getTool().getToolFrame(), - SelectLanguageDialog.class, TIMEOUT_MILLIS); + SelectLanguageDialog langDialog = waitForDialogComponent(SelectLanguageDialog.class); assertNotNull(langDialog); pressButtonByText(langDialog, "Give me a language:"); waitForSwing(); @@ -463,8 +454,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - langDialog = waitForDialogComponent(env.getTool().getToolFrame(), - SelectLanguageDialog.class, TIMEOUT_MILLIS); + langDialog = waitForDialogComponent(SelectLanguageDialog.class); LanguageCompilerSpecPair chosenLang = new LanguageCompilerSpecPair("68000:BE:32:Coldfire", "default"); @@ -484,8 +474,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - langDialog = waitForDialogComponent(env.getTool().getToolFrame(), - SelectLanguageDialog.class, TIMEOUT_MILLIS); + langDialog = waitForDialogComponent(SelectLanguageDialog.class); pressButtonByText(langDialog, "Give me a language:"); waitForSwing(); @@ -510,7 +499,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT assertEquals(10101, chosenInt); // Now set int to some other value - Integer newInt = new Integer(123456); + Integer newInt = 123456; chosenInt = ask_TextInput(Integer.toString(newInt), () -> { return script.askInt("Ask Test", "Enter an integer:"); }); @@ -539,7 +528,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT assertEquals((long) Math.pow(2, 18), chosenLong); // Now set the long value to a different value - Long newLong = new Long((long) Math.pow(4, 28)); + Long newLong = (long) Math.pow(4, 28); chosenLong = ask_TextInput(Long.toString(newLong), () -> { return script.askLong("Ask Test", "Enter a long:"); }); @@ -649,21 +638,21 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT createScript(); // Compare default value to expected properties value - String[] choices = new String[] { "eenie", "meanie", "miney", "mo" }; + List choices = Arrays.asList("eenie", "meanie", "miney", "mo"); String chosen = ask_ComboInput(() -> { return script.askChoice("Ask Test", "Choose one:", choices, "mo"); }); assertEquals("meanie", chosen); // Set choice to a different value - String choice_eenie = choices[0]; + String choice_eenie = choices.get(0); chosen = ask_ComboInput(choice_eenie, () -> { return script.askChoice("Ask Test", "Choose one:", choices, "mo"); }); assertEquals(choice_eenie, chosen); // See if the last-set value is auto-populated - String choice_miney = choices[2]; + String choice_miney = choices.get(2); chosen = ask_ComboInput(() -> { // Note: we are passing a default of 'miney', but expect the last choice of 'eenie' return script.askChoice("Ask Test", "Choose one:", choices, choice_miney); @@ -681,13 +670,13 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT public void testAskChoiceDefaultValue() throws Exception { createScript(); - String[] choices = new String[] { "one fish", "two fish", "red fish", "blue fish" }; + List choices = Arrays.asList("one fish", "two fish", "red fish", "blue fish"); int choiceIndex = 2; String chosen = ask_ComboInput(() -> { return script.askChoice("Ask Default Choice Test", - "Which choice would you like to pick?", choices, choices[choiceIndex]); + "Which choice would you like to pick?", choices, choices.get(choiceIndex)); }); - assertEquals(choices[choiceIndex], chosen); + assertEquals(choices.get(choiceIndex), chosen); } // TODO test for askChoices() @@ -739,8 +728,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - DialogComponentProvider askDialog = waitForDialogComponent(env.getTool().getToolFrame(), - DialogComponentProvider.class, TIMEOUT_MILLIS); + DialogComponentProvider askDialog = waitForDialogComponent(DialogComponentProvider.class); assertNotNull(askDialog); if (optionalValue != null) { @@ -774,8 +762,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - DialogComponentProvider askDialog = waitForDialogComponent(env.getTool().getToolFrame(), - DialogComponentProvider.class, TIMEOUT_MILLIS); + DialogComponentProvider askDialog = waitForDialogComponent(DialogComponentProvider.class); assertNotNull(askDialog); if (optionalValue != null) { @@ -808,8 +795,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT } }, false); - AskDialog askDialog = - waitForDialogComponent(env.getTool().getToolFrame(), AskDialog.class, TIMEOUT_MILLIS); + AskDialog askDialog = waitForDialogComponent(AskDialog.class); assertNotNull(askDialog); if (optionalValue != null) { @@ -890,7 +876,7 @@ public class GhidraScriptAskMethodsTest extends AbstractGhidraHeadedIntegrationT // test stub } }; - script.set(state, TaskMonitorAdapter.DUMMY_MONITOR, null); + script.set(state, TaskMonitor.DUMMY, null); URL url = GhidraScriptTest.class.getResource("GhidraScriptAsk.properties"); assertNotNull("Test cannot run without properties file!", url); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptTest.java index e25cf978c7..dd05284ae5 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptTest.java @@ -44,7 +44,7 @@ import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.TestEnv; import ghidra.util.Msg; import ghidra.util.exception.AssertException; -import ghidra.util.task.TaskMonitorAdapter; +import ghidra.util.task.TaskMonitor; public class GhidraScriptTest extends AbstractGhidraHeadedIntegrationTest { @@ -666,7 +666,6 @@ public class GhidraScriptTest extends AbstractGhidraHeadedIntegrationTest { assertEquals(values.size(), userChoices.size()); } - @SuppressWarnings("deprecation") @Test public void testAskChoices_NoSharedInterface_ChooseMultiple_Deprecated() throws Exception { @@ -674,13 +673,13 @@ public class GhidraScriptTest extends AbstractGhidraHeadedIntegrationTest { final GhidraScript script = getScript(); - Object[] values = { new JPanel(), new String() }; - String[] labels = { "Panel", "String" }; + List values = Arrays.asList(new JPanel(), new String()); + List labels = Arrays.asList("Panel", "String"); - AtomicReference ref = new AtomicReference<>(); + AtomicReference> ref = new AtomicReference<>(); runSwing(() -> { try { - Object[] userChoices = + List userChoices = script.askChoices("Ask Choices Test", "Pick", values, labels); ref.set(userChoices); } @@ -689,16 +688,15 @@ public class GhidraScriptTest extends AbstractGhidraHeadedIntegrationTest { } }, false); - MultipleOptionsDialog dialog = waitForDialogComponent(env.getTool().getToolFrame(), - MultipleOptionsDialog.class, DEFAULT_WINDOW_TIMEOUT); + MultipleOptionsDialog dialog = waitForDialogComponent(MultipleOptionsDialog.class); assertNotNull(dialog); pressSelectAll(dialog); pressButtonByText(dialog, "OK"); waitForSwing(); - Object[] userChoices = ref.get(); - assertEquals(values.length, userChoices.length); + List userChoices = ref.get(); + assertEquals(values.size(), userChoices.size()); } @Test @@ -777,7 +775,7 @@ public class GhidraScriptTest extends AbstractGhidraHeadedIntegrationTest { // test stub } }; - script.set(state, TaskMonitorAdapter.DUMMY_MONITOR, null); + script.set(state, TaskMonitor.DUMMY, null); return script; } diff --git a/Ghidra/Features/FunctionID/ghidra_scripts/CreateMultipleLibraries.java b/Ghidra/Features/FunctionID/ghidra_scripts/CreateMultipleLibraries.java index c47cbfc49e..40fd19d123 100644 --- a/Ghidra/Features/FunctionID/ghidra_scripts/CreateMultipleLibraries.java +++ b/Ghidra/Features/FunctionID/ghidra_scripts/CreateMultipleLibraries.java @@ -18,42 +18,21 @@ // Subfolders at a specific depth from this root form the roots of individual libraries // Library Name, Version, and Variant are created from the directory path elements //@category FunctionID -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.io.*; +import java.util.*; import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.TreeSet; import generic.hash.FNV1a64MessageDigest; import generic.hash.MessageDigest; import ghidra.app.script.GhidraScript; -import ghidra.feature.fid.db.FidDB; -import ghidra.feature.fid.db.FidFile; -import ghidra.feature.fid.db.FidFileManager; -import ghidra.feature.fid.db.LibraryRecord; +import ghidra.feature.fid.db.*; import ghidra.feature.fid.hash.FidHashQuad; -import ghidra.feature.fid.service.FidPopulateResult; +import ghidra.feature.fid.service.*; import ghidra.feature.fid.service.FidPopulateResult.Disposition; -import ghidra.feature.fid.service.FidPopulateResultReporter; -import ghidra.feature.fid.service.FidService; -import ghidra.feature.fid.service.Location; -import ghidra.framework.model.DomainFile; -import ghidra.framework.model.DomainFolder; -import ghidra.framework.model.DomainObject; +import ghidra.framework.model.*; import ghidra.program.database.ProgramContentHandler; import ghidra.program.model.lang.LanguageID; -import ghidra.program.model.listing.Function; -import ghidra.program.model.listing.FunctionIterator; -import ghidra.program.model.listing.FunctionManager; -import ghidra.program.model.listing.Program; +import ghidra.program.model.listing.*; import ghidra.program.model.mem.MemoryAccessException; import ghidra.util.Msg; import ghidra.util.exception.CancelledException; @@ -122,7 +101,7 @@ public class CreateMultipleLibraries extends GhidraScript { } } outputLine("List of unresolved symbols:"); - TreeSet symbols = new TreeSet(); + TreeSet symbols = new TreeSet<>(); for (Location location : result.getUnresolvedSymbols()) { symbols.add(location.getFunctionName()); } @@ -183,7 +162,7 @@ public class CreateMultipleLibraries extends GhidraScript { private boolean checkForDuplicate(ArrayList programs) throws CancelledException { String fullName = currentLibraryName + ':' + currentLibraryVersion + ':' + currentLibraryVariant; - ArrayList hashList = new ArrayList(); + ArrayList hashList = new ArrayList<>(); for (int i = 0; i < programs.size(); ++i) { monitor.checkCanceled(); try { @@ -216,7 +195,7 @@ public class CreateMultipleLibraries extends GhidraScript { private boolean detectDups(DomainFolder folder) { boolean isDuplicate = false; try { - ArrayList programs = new ArrayList(); + ArrayList programs = new ArrayList<>(); findPrograms(programs, folder); isDuplicate = checkForDuplicate(programs); @@ -241,7 +220,7 @@ public class CreateMultipleLibraries extends GhidraScript { return; } BufferedReader reader = new BufferedReader(new FileReader(commonSymbolsFile)); - commonSymbols = new LinkedList(); + commonSymbols = new LinkedList<>(); String line = reader.readLine(); while (line != null) { monitor.checkCanceled(); @@ -291,7 +270,7 @@ public class CreateMultipleLibraries extends GhidraScript { } private void populateLibrary(DomainFolder folder) { - ArrayList programs = new ArrayList(); + ArrayList programs = new ArrayList<>(); try { findPrograms(programs, folder); @@ -363,16 +342,16 @@ public class CreateMultipleLibraries extends GhidraScript { // ignore, means we use console } if (askYesNo("Do Duplication Detection", "Do you want to detect duplicates")) { - duplicatemap = new TreeMap(); + duplicatemap = new TreeMap<>(); } List nonInstallationFidFiles = FidFileManager.getInstance().getUserAddedFiles(); - Object[] FidFile = nonInstallationFidFiles.toArray(); if (nonInstallationFidFiles.isEmpty()) { throw new FileNotFoundException("Could not find any fidb files that can be populated"); } - fidFile = (FidFile) askChoice("Choose destination FidDB", - "Please choose the destination FidDB for population", FidFile, FidFile[0]); + fidFile = askChoice("Choose destination FidDB", + "Please choose the destination FidDB for population", nonInstallationFidFiles, + nonInstallationFidFiles.get(0)); rootFolder = askProjectFolder("Select root folder containing all libraries (at a depth of " + diff --git a/Ghidra/Features/FunctionID/ghidra_scripts/FindFunctionByHash.java b/Ghidra/Features/FunctionID/ghidra_scripts/FindFunctionByHash.java index b2e0a16428..890204b81a 100644 --- a/Ghidra/Features/FunctionID/ghidra_scripts/FindFunctionByHash.java +++ b/Ghidra/Features/FunctionID/ghidra_scripts/FindFunctionByHash.java @@ -16,6 +16,9 @@ // Opens all programs under a chosen domain folder, scans them for functions // that match a user supplied FID hash and prints info about the matching function //@category FunctionID +import java.io.IOException; +import java.util.*; + import ghidra.app.script.GhidraScript; import ghidra.feature.fid.hash.FidHashQuad; import ghidra.feature.fid.plugin.HashLookupListMode; @@ -29,9 +32,6 @@ import ghidra.util.NumericUtilities; import ghidra.util.exception.CancelledException; import ghidra.util.exception.VersionException; -import java.io.IOException; -import java.util.ArrayList; - public class FindFunctionByHash extends GhidraScript { FidService service; @@ -40,24 +40,23 @@ public class FindFunctionByHash extends GhidraScript { protected void run() throws Exception { service = new FidService(); - DomainFolder folder = - askProjectFolder("Please select a project folder to RECURSIVELY look for a named function:"); - String hashString = - askString("Please enter function hash", - "Please enter the (hex) function hash you're looking for:"); + DomainFolder folder = askProjectFolder( + "Please select a project folder to RECURSIVELY look for a named function:"); + String hashString = askString("Please enter function hash", + "Please enter the (hex) function hash you're looking for:"); long hash = NumericUtilities.parseHexLong(hashString); - HashLookupListMode[] choices = - new HashLookupListMode[] { HashLookupListMode.FULL, HashLookupListMode.SPECIFIC }; - HashLookupListMode hashType = - askChoice("Please choose hash type", "Please select the type of hash", choices, - choices[1]); + List choices = + Arrays.asList(HashLookupListMode.FULL, HashLookupListMode.SPECIFIC); + HashLookupListMode hashType = askChoice("Please choose hash type", + "Please select the type of hash", choices, choices.get(1)); - ArrayList programs = new ArrayList(); + ArrayList programs = new ArrayList<>(); findPrograms(programs, folder); findFunction(programs, hash, hashType); } - private void findFunction(ArrayList programs, long hash, HashLookupListMode hashType) { + private void findFunction(ArrayList programs, long hash, + HashLookupListMode hashType) { for (DomainFile domainFile : programs) { if (monitor.isCancelled()) { return; @@ -76,7 +75,8 @@ public class FindFunctionByHash extends GhidraScript { continue; } if ((hashType == HashLookupListMode.FULL && hashQuad.getFullHash() == hash) || - (hashType == HashLookupListMode.SPECIFIC && hashQuad.getSpecificHash() == hash)) { + (hashType == HashLookupListMode.SPECIFIC && + hashQuad.getSpecificHash() == hash)) { println("found " + function.getName() + " at " + function.getEntryPoint() + " in " + domainFile.getPathname()); }