Class HeadlessScript


public abstract class HeadlessScript extends GhidraScript
This class is analogous to GhidraScript, except that is only meant to be used with the HeadlessAnalyzer. That is, if a user writes a script that extends HeadlessScript, it should only be run in the Headless environment.
  • Constructor Details

    • HeadlessScript

      public HeadlessScript()
  • Method Details

    • storeHeadlessValue

      public void storeHeadlessValue(String key, Object value) throws ImproperUseException
      Stores a key/value pair in the HeadlessAnalyzer instance for later use.

      This method, along with the 'getStoredHeadlessValue' method, is useful for debugging and testing the Headless Analyzer (when the user has directly instantiated the HeadlessAnalyzer instead of running it from analyzeHeadless.sh or analyzeHeadless.bat). This method is intended to allow a HeadlessScript to store variables that reflect the current state of processing (at the time the script is being run). Storing variables in the HeadlessAnalyzer instance may be the only way to access the state of processing during cases when the user is forced to run in -readOnly mode, or if there is a value that is only accessible at the scripts stage.

      Parameters:
      key - storage key in String form
      value - value to store
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
      See Also:
    • getStoredHeadlessValue

      public Object getStoredHeadlessValue(String key) throws ImproperUseException
      Get stored value by key from the HeadlessAnalyzer instance.

      This method, along with the 'storedHeadlessValue' method, is useful for debugging and testing the Headless Analyzer (when the user has directly instantiated the HeadlessAnalyzer instead of running it from analyzeHeadless.sh or analyzeHeadless.bat). This method is intended to allow a HeadlessScript to store variables that reflect the current state of processing (at the time the script is being run). Storing variables in the HeadlessAnalyzer instance may be the only way to access the state of processing during cases when the user is forced to run in -readOnly mode, or if there is a value that is only accessible at the scripts stage.

      Parameters:
      key - key to retrieve the desired stored value
      Returns:
      stored Object, or null if none exists for that key
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
      See Also:
    • headlessStorageContainsKey

      public boolean headlessStorageContainsKey(String key) throws ImproperUseException
      Returns whether the specified key was stored in the HeadlessAnalyzer instance.
      Parameters:
      key - value of key to check for in Headless Analyzer instance
      Returns:
      true if the specified key exists
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
      See Also:
    • setHeadlessContinuationOption

      public void setHeadlessContinuationOption(HeadlessScript.HeadlessContinuationOption option)
      Sets the continuation option for this script

      The continuation option specifies whether to continue or abort follow-on processing, and whether to delete or keep the current program.

      Parameters:
      option - HeadlessContinuationOption set by this script
      See Also:
    • getHeadlessContinuationOption

      public HeadlessScript.HeadlessContinuationOption getHeadlessContinuationOption()
      Returns the continuation option for the current script (if one has not been set in this script, the option defaults to CONTINUE).

      The continuation option specifies whether to continue or abort follow-on processing, and whether to delete or keep the current program.

      Returns:
      the current HeadlessContinuationOption
      See Also:
    • enableHeadlessAnalysis

      public void enableHeadlessAnalysis(boolean b) throws ImproperUseException
      Enables or disables analysis according to the passed-in boolean value.

      A script that calls this method should run as a 'preScript', since preScripts execute before analysis would typically run. Running the script as a 'postScript' is ineffective, since the stage at which analysis would have happened has already passed.

      This change will persist throughout the current HeadlessAnalyzer session, unless changed again (in other words, once analysis is enabled via script for one program, it will also be enabled for future programs in the current session, unless changed).

      Parameters:
      b - true to enable analysis, false to disable analysis
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
      See Also:
    • isHeadlessAnalysisEnabled

      public boolean isHeadlessAnalysisEnabled() throws ImproperUseException
      Returns whether analysis is currently enabled or disabled in the HeadlessAnalyzer.
      Returns:
      whether analysis has been enabled or not
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
      See Also:
    • isImporting

      public boolean isImporting() throws ImproperUseException
      Returns whether the headless analyzer is currently set to -import mode or not (if not, it is in -process mode). The use of -import mode implies that binaries are actively being imported into the project (with optional scripts/analysis). The use of -process mode implies that existing project files are being processed (using scripts and/or analysis).
      Returns:
      whether we are in -import mode or not
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
    • setHeadlessImportDirectory

      public void setHeadlessImportDirectory(String importDir) throws ImproperUseException, IOException, InvalidNameException
      Changes the path in the Ghidra project where imported files are saved. The passed-in path is assumed to be relative to the project root. For example, if the directory structure for the Ghidra project looks like this:
                      MyGhidraProject:
                        /dir1
                          /innerDir1
                          /innerDir2
       
      Then the following usage would ensure that any files imported after this call would be saved in the MyGhidraProject:/dir1/innerDir2 folder.
                      setHeadlessImportDirectory("dir1/innerDir2");
       
      In contrast, the following usages would add new folders to the Ghidra project and save the imported files into the newly-created path:
                      setHeadlessImportDirectory("innerDir2/my/folder");
       
      changes the directory structure to:
                      MyGhidraProject:
                        /dir1
                          /innerDir1
                          /innerDir2
                            /my
                              /folder
       
      and:
                      setHeadlessImportDirectory("newDir/saveHere");
       
      changes the directory structure to:
                      MyGhidraProject:
                        /dir1
                          /innerDir1
                              /innerDir2
                        /newDir
                          /saveHere
       
      As in the examples above, if the desired folder does not already exist, it is created.

      A change in the import save folder will persist throughout the current HeadlessAnalyzer session, unless changed again (in other words, once the import directory has been changed, it will remain the 'save' directory for import files in the current session, unless changed).

      To revert back to the default import location (that which was specified via command line), pass the null object as the argument to this method, as below:

                      setHeadlessImportDirectory(null);       // Sets import save directory to default
       
      If a file with the same name already exists in the desired location, it will only be overwritten if "-overwrite" is true.

      This method is only applicable when using the HeadlessAnalyzer -import mode and is ineffective in -process mode.

      Parameters:
      importDir - the absolute path (relative to root) where inputs will be saved
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
      IOException - if there are issues creating the folder
      InvalidNameException - if folder name is invalid
    • analysisTimeoutOccurred

      public boolean analysisTimeoutOccurred() throws ImproperUseException
      Returns whether analysis for the current program has timed out.

      Analysis will time out only in the case where:

      1. the users has set an analysis timeout period using the -analysisTimeoutPerFile parameter
      2. analysis is enabled and has completed
      3. the current script is being run as a postScript (since postScripts run after analysis)
      Returns:
      whether analysis timeout occurred
      Throws:
      ImproperUseException - if not in headless mode or headless instance not set
    • runScript

      public void runScript(String scriptName, String[] scriptArguments, GhidraState scriptState) throws Exception
      Description copied from class: GhidraScript
      Runs a script by name with the given arguments using the given state.

      It attempts to locate the script in the directories defined in GhidraScriptUtil.getScriptDirectories().

      The script being run uses the given GhidraState (e.g., script variables) Any changes to the state by the script being run will be reflected in the given state object. If the given object is the current state, the this scripts state may be changed by the called script.

      Overrides:
      runScript in class GhidraScript
      Parameters:
      scriptName - the name of the script to run
      scriptArguments - the arguments to pass to the script
      scriptState - the Ghidra state
      Throws:
      Exception - if any exceptions occur while running the script
      See Also:
    • cleanup

      public void cleanup(boolean success)
      Description copied from class: GhidraScript
      A callback for scripts to perform any needed cleanup after the script is finished
      Overrides:
      cleanup in class GhidraScript
      Parameters:
      success - true if the script was successful